import numpy as np
import librosa as lr
import librosa.display
# Read the audio file using librosa
y, sr = librosa.load('Ex3_sound1.wav')
# We need to convert from type float 32 to binary in order to extract the LSB.
# The following funciton do just that.
import struct
def binary(num):
return ''.join('{:0>8b}'.format(c) for c in struct.pack('!f', num))
# Confirm the binary representation of the float is correct using the following online convertor
# https://www.h-schmidt.net/FloatConverter/IEEE754.html
for i in range(0,16):
val = binary(y[i])
print(val)
# Create empty list to save all the lsb values from every sample
lsbList = []
# Next we'll convert every sample in the audio file
for sample in y:
binaryVal = binary(sample)
lsbList.append(binaryVal[31])
print(lsbList[0:16])
10111011011001111000010001100010 10111011000110100101111111000011 10111011011011011110111001100000 10111011010100011010110111001100 10111011011010011100100011000011 10111011100010000000000011110001 10111011111001010111001101010110 10111100001100001111111001000111 10111011110100000010010110010100 10111100000011001101010010101101 10111011111111010001000101001000 10111100010001111100111010011100 10111011100110000000101001110111 10111011010010100011001010101110 10111011010001010101100001110000 00111011101011110110101010111100 ['0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '0', '0']
# Pair up the digits in pairs of 8 so that ASCI conversion to characters can be used
librosaString = "".join(chr(int("".join(map(str,lsbList[i:i+8])),2)) for i in range(0,len(lsbList),8))
print(librosaString[0:50])
# The text below does not make any sense. Try a different method.
MH<ì+ð¢A³Döéûnâa-ýZÐÚ& ìƯ~i³9Rí;èPMR
# Open the audio file using wave
import wave
audio = wave.open("Ex3_sound1.wav", mode='rb')
# get the audio data
dataPoints = bytearray(list(audio.readframes(audio.getnframes())))
# Get the LSB of each byte using the bitwise method
lsbs = [dataPoints[i] & 1 for i in range(len(dataPoints))]
# add the lsbs together into pairs of 8 so that they can be converted into asci characters
asciChr = "".join(chr(int("".join(map(str,lsbs[i:i+8])),2)) for i in range(0,len(lsbs),8))
# We can already see the message here, but need to remove the # characters at the end of the string
print(asciChr[:50])
# split the text based on the # character and save the 1st section of the split
msg = asciChr.split("#")[0]
# Print the hidden message
print(msg)
audio.close()
Mom I will not be home for supper################# Mom I will not be home for supper
# We can see wehere the error came in using librosa just by comparing the first 16 lsb bits
# Librosa loads audio samples as floats, so when converted to binary, the data differ from the wave method above.
print(lsbList[0:16]) # librosa library
print(lsbs[0:16]) # wave library
['0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '0', '0'] [0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1]