简体   繁体   English

使用 lsb 的音频隐写术在带有隐藏消息的音频中引起噪音

[英]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 文件,但根据您的评论,您的文件的sampwidth2 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. (因为nchannels1 ,每帧有一个样本,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM