BPC 电波授时信号 Python 转 js 实现一半 求助

2017-03-14 15:39:06 +08:00
 guxin0123

来源 http://www.hackrf.net

有个六局电波的西铁城,由于地理位置偏僻收不到波

网上看到了这个 《 BPC 电波授时信号的“零成本”伪造》 用 Python+耳机发射授时信号

上网查了查 在苹果商店发现一个 app 售价 12 但是没有苹果手机

觉得要是把他的代码改到 js 里面就可以在浏览器里面运行对时就非常方便了

目前只完成了时间转 base4 部分 但是 js 音频发声转换部分没有思路 对音频和波形没有研究过

看了两个库 timbre.js 和 lame.js 不知是否可行

python 代码

# -*- coding: utf-8 -*-
"""
Created on Tue Jan 19 15:26:45 2016

@author: zhengbowang
"""
import pyaudio
import struct
import datetime
import math

def dropandfill(l,s):return '0'*(l - len(s[2:])) + s[2:]#用 0 补位
def time2code(date_time, dt = datetime.timedelta(0)):

#将时间转换成 BPC 编码。

    date_time -= dt
    date = [date_time.day, date_time.month, date_time.year]
    timet = [date_time.hour,date_time.minute,date_time.weekday()+1]
    date[2] = date[2]%100#year
    timet[0] = timet[0]%12#am.pm
    p1 = dropandfill(2,bin(date_time.second/20))#seconds
    p2 = '00'#reserved
    sec1 = (p1+p2)+''.join(map(dropandfill,[4,6,4],map(bin,timet)))
    p31 = str(int(date_time.hour>=12))
    p32 = str((sec1.count('1'))%2)
    p3 = p31 + p32
    sec2 = ''.join(map(dropandfill,[6,4,6],map(bin,date)))
    p41 = str(int(date_time.year%1000>100))
    p42 = str(((sec2.count('1'))%2))
    p4 = p41 + p42
    code2 = sec1 + p3 +sec2 + p4
    bin2four = {'00':'1','01':'2','10':'3','11':'4'}#to base4
    return '0'+''.join([bin2four[code2[2*i:2*i+2]] for i in range(len(code2)/2)])

dt = datetime.timedelta(hours = 1)#fake time shift
samp_rate = 68500
freq = 6850 * 2 #in Hertz
ttime =20 #in Sec
SAMPLE_LEN = samp_rate * ttime # 20 seconds of cosine
value = ampl = 32725
div = samp_rate/freq/2
data = 32725
# 打开声音输出流
p = pyaudio.PyAudio()
stream = p.open(format = 8,
                channels = 1,
                rate = samp_rate,
                output = True)

while True:
    date_time = datetime.datetime.now()+dt
    print date_time
    sec = (date_time.second+1)%20
    code_str = time2code(date_time)
    start = sec * samp_rate
    for i in xrange((start), SAMPLE_LEN):
        #if i % div == 0:value = -value#carrier generate
        value = ampl * int(math.cos(math.pi / float(div) * float(i)))
        pulse = (i - sec * samp_rate)/(samp_rate / 10)
        packed_value = struct.pack('h', int(pulse >= int(code_str[sec]))*value)
        stream.write(packed_value)
        if i % samp_rate == 0 and i != start: 
            sec = sec + 1

转到一半的 js 代码

function time2code(date_time) {
            var date = [date_time.getDate(), date_time.getMonth() + 1, date_time.getFullYear()];
            var timet = [date_time.getHours(), date_time.getMinutes(), date_time.getUTCDay()];
            date[2] = date[2] % 100; //year
            timet[0] = timet[0] % 12; //am,pm
            var p1 = dropandfill(2, parseInt(date_time.getSeconds() / 20).toString(2)); //seconds
            var p2 = '00'; //reserved
            var sec1 = (p1 + p2) + '' + join(map(dropandfill, [4, 6, 4], map(bin, timet)))
            var p31 = Number(date_time.getHours() >= 12).toString();
            var re = new RegExp("1", "g");
            var p32 = str((sec1.match(re).length) % 2)
            var p3 = p31 + p32;

            var sec2 = '' + join(map(dropandfill, [6, 4, 6], map(bin, date)));
            var p41 = str(Number(date_time.getFullYear() % 1000 > 100))
            var p42 = str(((sec2.match(re).length) % 2))
            var p4 = p41 + p42
            var code2 = sec1 + p3 + sec2 + p4
            var bin2four = { '00': '1', '01': '2', '10': '3', '11': '4' } //to base4
            var ret = [];
            ret.push('0')
            for (var i = 0; i < code2.length / 2; i++) {
                ret.push(bin2four[code2.substring(i * 2, i * 2 + 2)]);
            }
            return join(ret);
        }

        //用 0 补位
        function dropandfill(size, num) {
            var s = "000000000" + num;
            return s.substr(s.length - size);
        }

        function map(a, b) {
            if (arguments.length == 2) {
                for (var i = 0; i < arguments[1].length; i++) {
                    arguments[1][i] = arguments[0](arguments[1][i]);
                }
                return arguments[1];
            }
            if (arguments.length == 3) {
                for (var i = 0; i < arguments[1].length; i++) {
                    arguments[1][i] = arguments[0](arguments[1][i], arguments[2][i]);
                }
                return arguments[1];
            }

        }
        function bin(e) {
            return e.toString(2);
        }
        function join(e) {
            var ret = "";
            for (var i = 0; i < e.length; i++) {
                ret += e[i];
            }
            return ret;
        }
        function str(e) {
            return e.toString();
        }
2766 次点击
所在节点    程序员
2 条回复
GPU
2017-08-08 18:39:21 +08:00
好像还有一个 68.5kHz 的 5 倍频要处理
guxin0123
2017-08-08 19:27:05 +08:00
发现一个别人做好的了

https://shogo82148.github.io/web-jjy/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/347395

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX