信息隐藏—音频隐藏LSB算法

尝试用python做音频的LSB隐藏算法,过程是曲折的,虽然结果还有一些瑕疵,毕竟对音频的信号处理还不太熟练,不过结果总算是成功了。

1.环境

win10操作系统、pycharm编辑器、python3.9、第三方库:librosa、bitarray

1.1安装bitarray

之所以选择安装bitarray是为了解决中英文字符串和二进制字符串的转化问题

pip install bitarray

1.2安装librosa

它是一个Python模块,通常用于分析音频信号,但更倾向于音乐。它包括用于构建MIR(音乐信息检索)系统的nuts 和 bolts。 

pip install librosa

2.转码函数

def str2bitarray(s):
    s.replace(r'\n', '')
    ret = bitarray(''.join([bin(int('1' + hex(c)[2:], 16))[3:] for c in s.encode('utf-8')]))
    return ret

def bitarray2str(bit):
    bit = bitarray(bit)
    print(bit)
    return bit.tobytes().decode('utf-8')

 str2bitarray()函数:作用是将文本文件中读取出字符串转码为二进制字符串

bitarray2str()函数:作用是将解密后的二进制字符串转码为明文

3. 原理

上述是图像的lsb隐藏算法,音频也是类似的

一言以蔽之,假如某个音频的采样点为32位float类型,那么替换掉其中一些不太重要的位置,对音频的影响不大,极难发现。如0.005689改为0.005680。

4.算法实现

import librosa
from bitarray import bitarray
import soundfile as sf
import numpy as np

bit_float = {'00': 0.000001, '01': 0.000002, '10': 0.000003, '11': 0.000004}
float_bit = {8:'00',9:'00',10:'00',11:'00',18:'01',19:'01',20:'01',21:'01',28:'10',29:'10',30:'10',31:'10',38:'11',39:'11',40:'11',41:'11'}

def str2bitarray(s):
    s.replace(r'\n', '')
    ret = bitarray(''.join([bin(int('1' + hex(c)[2:], 16))[3:] for c in s.encode('utf-8')]))
    return ret

def bitarray2str(bit):
    bit = bitarray(bit)
    print(bit)
    return bit.tobytes().decode('utf-8')

def bit2float(bit):
    if bit.to01() in bit_float.keys():
        return bit_float[bit.to01()]

def float2bit(float):
    if float in bit_float.values():
        for key, value in bit_float.items():
            if float == value:
                return key

def LSB(audiofile, hidefile):
    data, sr = librosa.load(audiofile)

    #隐藏的文本
    infor = ''
    with open(hidefile, 'rb') as f:
        infor = str2bitarray(f.read().decode('utf-8'))

    start = 0
    end = 2
    for i in range(len(infor)):
        if bit2float(infor[start:end]) == None:
            break
        data[i] = data[i] + bit2float(infor[start:end])
        start += 2
        end += 2

    #librosa.output.write_wav(r'C:\Users\adins\Desktop\example.wav', data)
    sf.write(r'C:\Users\adins\Desktop\example.wav', data,samplerate=sr, subtype='PCM_24')

def UNLSB(audiofile , hidedfile):
    data, sr = librosa.load(audiofile)
    hidedata , sr1 = librosa.load(hidedfile)

    infor = ''
    for i in range(len(data)):
        item = int((hidedata[i] - data[i])*10000000)
        if item in float_bit.keys():
            infor = infor + float_bit[item]
        if item < 5:
            break

    infor = bitarray2str(infor)

    with open(r'..\2.txt', 'w') as f:
        f.write(infor)

LSB(r'C:\Users\adins\Desktop\0020a.wav', r'C:\Users\adins\Desktop\1.txt')
UNLSB(r'C:\Users\adins\Desktop\0020a.wav', r'C:\Users\adins\Desktop\example.wav')

LSB('音频载体_WAV格式',’密文‘):加密函数

UNLSB('加密前音频',’加密后的音频‘):解密函数

4.1 缺陷

由于python没有指针,故没有好办法来对float型采样点做某一位上的操作,这里采用的是投机取巧的办法,定义了一个字典bit_float = {'00': 0.000001, '01': 0.000002, '10': 0.000003, '11': 0.000004}

使得将每两位二进制转化为float型与原采样点相加,再用原采样点与加密后的采样点的差值作为提取时的判断标准。这样带来的缺点十分明显,第一解密时需要与原载体做对比才能导出明文,第二,由于是做的float型加法,所得为近似值,不够稳定,第三这种不是对某些位的操作会造成信息的利用率不高,嵌入容量低。

为了解决float型加减时为近似计算的弊端,在用隐藏信息的采样点减去原采样点时*10000000

int((hidedata[i] - data[i])*10000000)转为整数,取8、9、10、11近似为10,18、19、20、21近似为20,28、29、30、31近似为30。创建一个字典用来做转换

float_bit = {8:'00',9:'00',10:'00',11:'00',18:'01',19:'01',20:'01',21:'01',28:'10',29:'10',30:'10',31:'10',38:'11',39:'11',40:'11',41:'11'}

即差值*10000000为10的对应二进制’00‘,这也算做了一种编码`~`。

4.2加密对比

加密前后的波形图无明显区别 

测试中英文均可行。

librosa_test.py-系统安全文档类资源-CSDN下载 

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值