LSB音频隐写报错:unsupported operand type(s) for &: 'str' and 'int' 修复
问题描述
运行LSB音频隐写函数时出现错误:
unsupported operand type(s) for &: 'str' and 'int'
用户代码如下:
def lsb(bineraudio, binermod): # bineraudio = 0000000000000000000000000001100001100110011101000111100101110000011001000110000101110011011010000000000000000000000000000000000001101001011100110110111100110110011011010111000000110100001100010000 # binermod = 1111000010101111110000000110111110001111110111110100111111100000000000000101000000110000011011111000000000101111010000001110 for i, bit in enumerate(binermod): bineraudio[i] = (bineraudio[i] & 254) | bit # Get the modified bytes frame_modified = bytes(bineraudio) with open('txt/'+'binary.txt', 'w') as file1: file1.write(frame_modified.bin) # variables binarypass and binaryaudio contain the binary digits 1 and 0.
用户问题:如何修复该错误,或是如何通过LSB方法将调制后的消息嵌入到音频中?
错误原因与修复方案
错误根源
bineraudio和binermod都是二进制字符串,但位运算(&、|)要求操作数是整数类型,直接对字符串和整数做位运算就会触发类型错误。
修复步骤
转换数据类型
- 音频二进制字符串:按每8位一组分割,转成整数(对应一个字节),组成可修改的列表(字符串不可直接修改)。
- 消息二进制字符串:将每个字符转成整数0或1。
修正位运算逻辑
对音频的每个字节,先清空最低位(& 254,二进制11111110),再将消息的对应位写入最低位(| bit)。修正文件写入逻辑
- 如果要保存修改后的字节数据,需用二进制模式(
wb)写入文件; - 如果要保存二进制字符串,需将修改后的字节数组转回二进制字符串。
- 如果要保存修改后的字节数据,需用二进制模式(
修正后的代码示例
def lsb(bineraudio, binermod): # 1. 将音频二进制字符串转成字节整数列表(每8位一个字节) # 补零确保长度是8的倍数 if len(bineraudio) % 8 != 0: bineraudio = bineraudio.ljust(len(bineraudio) + (8 - len(bineraudio) % 8), '0') audio_bytes = [int(bineraudio[i:i+8], 2) for i in range(0, len(bineraudio), 8)] # 2. 将消息二进制字符串转成整数列表(0/1) msg_bits = [int(bit) for bit in binermod] # 3. 检查消息长度是否超过音频可容纳的位数(每个字节存1位) if len(msg_bits) > len(audio_bytes): raise ValueError("消息过长,音频容量不足") # 4. LSB嵌入 for i in range(len(msg_bits)): # 清空最低位,再写入消息位 audio_bytes[i] = (audio_bytes[i] & 254) | msg_bits[i] # 5. 保存结果 # 选项1:保存为二进制文件(适合后续还原音频) with open('txt/modified_audio.bin', 'wb') as f: f.write(bytes(audio_bytes)) # 选项2:保存为二进制字符串(和输入格式一致) modified_bin_str = ''.join([format(byte, '08b') for byte in audio_bytes]) with open('txt/binary.txt', 'w') as f: f.write(modified_bin_str) # 使用示例 binaryaudio = "0000000000000000000000000001100001100110011101000111100101110000011001000110000101110011011010000000000000000000000000000000000001101001011100110110111100110110011011010111000000110100001100010000" binarypass = "1111000010101111110000000110111110001111110111110100111111100000000000000101000000110000011011111000000000101111010000001110" lsb(binaryaudio, binarypass)
关键说明
- 音频二进制字符串必须按8位分割成字节,因为LSB隐写是基于字节的最低位操作;
- 要确保消息长度不超过音频的字节数(每个字节只能存1位消息);
- 保存时根据需求选择二进制文件或二进制字符串格式,二进制文件更适合后续还原音频数据。
内容的提问来源于stack exchange,提问作者HelpMeInDjango
相关产品推荐
相关产品推荐

