Skip to content

ZeroDaysCTF/secret_in_wav

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Audio steganography - Phase encoding

http://dsp.stackexchange.com/questions/14804/audio-steganography-using-phase-encoding-technique

Imports

import numpy as np
import scipy as sp
import scipy.io.wavfile

Settings

fname = 'brilliant.wav'
rate, channels = sp.io.wavfile.read(fname)
channels = channels.copy()
rate, channels.shape
(22050, (14595,))

Encode

msg = "super secret message!"
msglen = 8 * len(msg)
msglen
168
seglen = int(2 * 2**np.ceil(np.log2(2*msglen)))
segnum = int(np.ceil(channels.shape[0]/seglen))
segnum, seglen
(15, 1024)
if len(channels.shape) == 1:
    channels.resize(segnum*seglen, refcheck=False)
    channels = channels[np.newaxis]
else:
    channels.resize((segnum*seglen, channels.shape[1]), refcheck=False)
    channels = channels.T
channels.shape
(1, 15360)
channels.dtype
dtype('int16')
msgbin = np.ravel([[int(y) for y in format(ord(x), '08b')] for x in msg])
msgPi = msgbin.copy()
msgPi[msgPi == 0] = -1
msgPi = msgPi * -np.pi/2
segs = channels[0].reshape((segnum,seglen))
segs = np.fft.fft(segs)
M = np.abs(segs)
P = np.angle(segs)
print(M[0,:3])
print(P[0,:3])
[ 39859.          18443.44842853  40294.31380713]
[ 0.          2.8657574   2.70047085]
dP = np.diff(P, axis=0)
dP[0,:5]
array([ 0.        , -5.94549832, -5.66979862,  3.56063878,  3.56078846])
segmid = seglen // 2
P[0,-msglen+segmid:segmid] = msgPi
P[0,segmid+1:segmid+1+msglen] = -msgPi[::-1]
for i in range(1, len(P)): P[i] = P[i-1] + dP[i-1]
segs = (M * np.exp(1j * P))
segs = np.fft.ifft(segs).real
channels[0] = segs.ravel().astype(np.int16)
sp.io.wavfile.write('steg_'+fname, rate, channels.T)

Decode

msglen = 8 * 4
seglen = 2*int(2**np.ceil(np.log2(2*msglen)))
segmid = seglen // 2
if len(channels.shape) == 1:
    x = channels[:seglen]
else:
    x = channels[:seglen,0]
x = (np.angle(np.fft.fft(x))[segmid-msglen:segmid] < 0).astype(np.int8)
x = x.reshape((-1,8)).dot(1 << np.arange(8 - 1, -1, -1))
''.join(np.char.mod('%c',x))
'asdf'

About

A bit of Python code that hides ASCII message in wav file using phase encoding technique

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Jupyter Notebook 100.0%