[英]Audio Steganography using lsb causing noise in audio with hidden message
I am trying to solve a problem in my audio steganography code.我正在尝试解决我的音频隐写术代码中的问题。 Afted hiding the message in wav audio file, there is some noice which of course should not be there considering the point of the whole audio steganography.
Afted 将消息隐藏在 wav 音频文件中,考虑到整个音频隐写术的意义,当然不应该有一些噪音。 Thanks a lot for help !
非常感谢您的帮助!
here is the code这是代码
import wave
import os
global chosen_audio
def hide():
hide_menu()
global chosen_audio
message = input('Input message to be hidden: \n')
print('hiding message ... \n')
audio = wave.open(chosen_audio, 'rb')
frame_bytes = bytearray(list(audio.readframes(audio.getnframes())))
message = message + int((len(frame_bytes) - (len(message) * 8 * 8)) / 8) * '#'
bits = list(
map(int, ''.join([bin(ord(i)).lstrip('0b').rjust(8, '0') for i in message])))
for i, bit in enumerate(bits):
frame_bytes[i] = (frame_bytes[i] & 254) | bit # replace lsb
frames_modified = bytes(frame_bytes)
with wave.open('C:/Users/*****/PycharmProjects/steganography/modified_audio.wav', 'wb') as modified_audio:
modified_audio.setparams(audio.getparams())
modified_audio.writeframes(frames_modified)
print('message hidden ... \n')
modified_audio.close()
audio.close()
def reveal():
modified_audio = wave.open('C:/Users/*****/PycharmProjects/steganography/modified_audio.wav', 'rb')
frame_bytes = bytearray(list(modified_audio.readframes(modified_audio.getnframes())))
ls_bits = [frame_bytes[i] & 1 for i in range(len(frame_bytes))]
text = "".join(chr(int("".join(map(str, ls_bits[i:i + 8])), 2)) for i in range(0, len(ls_bits), 8))
message = text.split("###")[0]
modified_audio.close()
return message
def mode():
method = input(
' \n\t\t\tPLEASE, CHOOSE THE PROCEDURE! \n\n \tPRESS H FOR HIDING THE MESSAGE \t PRESS R FOR REVEALING THE MESSAGE FROM THE AUDIO\n')
if method == 'H' or method == 'h':
hide()
elif method == 'r' or method == 'R':
reveal()
else:
print('I don\'t think we have such a option')
mode()
def hide_menu():
global chosen_audio
chosen_option = ''
print(chosen_option)
chosen_option = ''
chosen_audio = ''
print(' \nCHOOSE YOUR AUDIO FILE! ')
chosen_option = (
input('\t press 1 & ENTER for your own audio path\n''\t press 2 & ENTER for default audio file\n'))
if chosen_option == '1':
file_path = input('Enter a file path: ')
if os.path.exists(file_path):
print('The path is okay, file exists!')
chosen_audio = file_path
else:
print('The specified file in this path does NOT exist')
hide_menu()
elif chosen_option == '2':
chosen_audio_option = input(
'\t press V & enter to use voice audio \t press S & enter to use sound audio\t press M & enter to use '
'song audio\n')
if chosen_audio_option == 'M' or chosen_audio_option == 'm':
chosen_audio = 'C:\\Users\\*****\\PycharmProjects\\steganography\\song_audio.wav'
elif chosen_audio_option == 'v' or chosen_audio_option == 'V':
chosen_audio = 'C:\\Users\\*****\\PycharmProjects\\steganography\\voice_audio.wav'
elif chosen_audio_option == 's' or chosen_audio_option == 'S':
chosen_audio = 'C:\\Users\\*****\\Desktop\\audio\\hracka_pes.wav'
else:
print('No such a option !')
hide_menu()
else:
print('I don\'t think we have such a option')
hide_menu()
def reveal_menu():
global chosen_audio
chosen_audio = ''
print(' \nCHOOSE YOUR AUDIO FILE! ')
chosen_option = int(
input('\t press 1 & ENTER for your own audio path\n''\t press 2 & ENTER for default audio file\n'))
if chosen_option == 1:
file_path = input('Enter a file path: ')
if os.path.exists(file_path):
print('The path is okay, file exists!')
chosen_audio = file_path
else:
print('The specified file in this path does NOT exist')
hide_menu()
elif chosen_option == 2:
pass
mode()
# menu()
# hide()
note - cannot use library for steganography注意 - 不能使用库进行隐写术
Hearing the noise in the modified_audio is the main problem听到 modified_audio 中的噪音是主要问题
Your code is written to deal with wave files where sampwidth=1
, but per your comment, the sampwidth
of your file is 2
.您编写的代码是为了处理
sampwidth=1
的 wave 文件,但根据您的评论,您的文件的sampwidth
是2
。 This means that your frame_bytes
array is not an array of samples, it's an array of bytes in which every two bytes together form one sample.这意味着您的
frame_bytes
数组不是一个样本数组,它是一个字节数组,其中每两个字节一起构成一个样本。 (And because nchannels
is 1
, there is one sample per frame, mono audio.) So when you changed the LSB of all the bytes , you were changing not only the LSB of each sample, but also a bit in the middle of it. (因为
nchannels
是1
,每帧有一个样本,mono 音频。)所以当你改变所有字节的 LSB 时,你不仅改变了每个样本的 LSB,而且改变了它中间的一点。
You should convert this to an array of samples, and then change the samples LSBs.您应该将其转换为样本数组,然后更改样本的 LSB。 You can use
array
for this:您可以为此使用
array
:
import array
samples = array.array('h', frame_bytes) # signed 16-bit
# ... modify the samples ...
frames_modified = samples.tobytes()
Of course, it would be best if your code checked beforehand if you're dealing with signed shorts ( sampsize==2
) or unsigned bytes ( sampsize==1
), and then handle them accordingly.当然,如果您处理的是有符号短裤 (
sampsize==2
) 或无符号字节 ( sampsize==1
),最好事先检查您的代码,然后相应地处理它们。 You might do something like:你可能会这样做:
samples = array.array('h' if sampsize == 2 else 'B', frame_bytes)
for i, bit in enumerate(bits):
samples[i] = samples[i] & -2 | bit
(I have not tested this much) (我没有测试这么多)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.