0x00 已知条件
给了一个godwave.wav,还有两个提示。
0x01 解法过程
- Hint1: 你们做音频题都不喜欢看时域图?
根据这个,用Cooledit看一下时域波形,如下:
发现波形明显整过,赋值差异很明显,数出周期为64个点。第一次做音频题,看一下writeup,写个脚本把它提取成01序列:
写的过程中值得注意的是:横轴改成smpl,即采样点,每个单位对应一个实心点;纵轴改成norm,表示幅值。这样在编程时,每个点就是横轴对应waveData[i],纵轴对应norm。
另外,判断每周期的值时,本来采用的是计算平均值。后来简化计算改成全部求和,先看了一下低赋值周期最大值不超过0.035,那么64个点最多也就2.24。(不知道题解的这个10是怎么取的,可能是为保险取大点吧)
[Python]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wave
import matplotlib.pyplot as plt
import numpy
import os
path = 'D:\PyCharm\Projects\CTF\Javis OJ\misc\god_wave\\'
wav = wave.open(path+'godwave.wav','rb')
params = wav.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
strData = wav.readframes(nframes) #读取音频,字符串格式
waveData = numpy.fromstring(strData, dtype=numpy.int16) #上述字符串转int
waveData = waveData*1.0/(max(abs(waveData))) #wave幅值归一化,与Cool edit的norm纵轴数值一致
#将音频转化为01串
string = ''
norm = 0
for i in range(1735680):
norm = norm+abs(waveData[i])
if (i+1) % 64 == 0:
if norm > 10:
string += '1'
else:
string += '0'
norm = 0
with open('01output.txt','w') as output:
output.writelines(string)
在输出文件中写了一行01串。
- Hint2: 在数据传输过程中,我们往往会使用一种自带时钟的编码以减少误码率
搜索“自带时钟的编码”,说是曼彻斯特编码。写脚本把上面得到的01串做曼彻斯特解码,负电平为1,正电平 为0:
# -*- coding: utf-8 -*-
file_in = open('01output.txt','r')
code = file_in.readline()
file_in.close()
le = len(str(code))
print le
print code
result = ''
count = 0
res = 0
while code != '':
cp = code[:2]
if cp != '':
if cp[0] == '0' and cp[1] == '1':
res = (res<<1)|0
count +=1
if cp[0] == '1' and cp[1] == '0':
res = (res<<1)|1
count +=1
if count == 8:
result += chr(res)
count = 0
res = 0
else:
print 'Unexpected cp, exit!' # found '00' or '11', stop the script directly
break
code = code[2:]
with open('result.png','wb') as file_out:
file_out.write(result)
一开始自己写的时候犯蠢,直接每两位出一位写到result里,写出来也打不开。
参(zhao)考(chao)题解用位运算, 逐字节(8位)转成字符写入。打开是个二维码,扫了即可。
也不知道题解怎么知道要存成PNG的……好吧自己试了一下只要是图片格式都能扫,随便选个格式就行。