音频子带置乱加密中两个NumPy数组为何完全相同?
子带置乱音频加密代码问题排查
问题描述
我正在开发基于子带置乱的音频信号加密程序,采用**置换矩阵(每行每列仅含一个1,其余为0)**实现子带混排。小型数组测试时功能正常——比如用密钥12212时,sb[:,0]和sb_midi[:,3]结果一致,但绘图时sb与sb_midi的频谱图完全相同,差值绘图也看不到任何差异。这是我的本科毕设项目,已经排查了大量bug仍未解决,求帮助。
相关代码
初始化代码
# 创建矩阵,每列存放一个抽选后的信号 sb = np.zeros((len(yll), n_sub)) sb[:,0] = yll sb[:,1] = ylh sb[:,2] = yhl sb[:,3] = yhh sb_out = np.zeros((len(yll), n_sub)) sb_midi = np.zeros((len(yll), n_sub)) x_out = np.array((n_sub*len(yll),1))
置换与绘图代码
# 自定义函数生成对应子带数量的置换矩阵 matriz = matriz_permutacion(key, n_sub) traspuesta = np.transpose(matriz) # 绘制原信号子带频谱 plt.figure(4) plt.plot(20*np.log10(abs(fft(sb))), color='red', label='x') plt.title('Sb') plt.xlabel('频率') # 注:原代码标注为"tiempo(时间)"错误,FFT横轴为频率 plt.ylabel('幅度(dB)') plt.savefig(r'Downloads\codigos_tfg\figuras\x.png') # 获取置换矩阵每行最大值的索引 i = np.argmax(matriz, axis=1) print(i) # 执行子带置换 for N in range(0, n_sub): j = i[N] sb_midi[:,j] = sb[:,N] # 绘制置换后信号子带频谱 plt.figure(5) plt.plot(20*np.log10(abs(fft(sb_midi))), color='red', label='x') plt.title('sb_midi') plt.xlabel('频率') plt.ylabel('幅度(dB)') plt.savefig(r'Downloads\codigos_tfg\figuras\x.png')
排查方向
置换矩阵合法性验证
- 直接打印
matriz的完整内容,确认它是标准置换矩阵(每行每列恰好一个1)。如果生成的是单位矩阵,置换后自然和原信号完全一致。 - 检查
matriz_permutacion函数逻辑:密钥12212是否生成了预期的映射规则?比如预期第0列映射到第3列,那么矩阵第0行第3列必须为1,其余位置为0。
- 直接打印
频谱绘图逻辑修正
- 原代码中
fft(sb)处理二维数组时,plt.plot会将所有列的频谱曲线叠加绘制。而子带置换只是调换列的顺序,叠加后曲线和原信号完全重合。 - 解决方法:分开绘制每一列的频谱,才能直观看到置换差异:
# 原信号各子带频谱分开绘制 plt.figure(4) for col in range(n_sub): plt.plot(20*np.log10(abs(fft(sb[:,col]))), label=f'子带 {col}') plt.title('原信号各子带频谱') plt.xlabel('频率') plt.ylabel('幅度(dB)') plt.legend() plt.savefig(r'Downloads\codigos_tfg\figuras\original_subbands.png') # 置换后各子带频谱分开绘制 plt.figure(5) for col in range(n_sub): plt.plot(20*np.log10(abs(fft(sb_midi[:,col]))), label=f'子带 {col}') plt.title('置换后各子带频谱') plt.xlabel('频率') plt.ylabel('幅度(dB)') plt.legend() plt.savefig(r'Downloads\codigos_tfg\figuras\permuted_subbands.png')
- 原代码中
文件保存覆盖问题
- 原代码中两张图都保存到同一个路径
x.png,后一张会直接覆盖前一张,导致你看到的两张图实际是同一张。记得修改保存文件名区分两者。
- 原代码中两张图都保存到同一个路径
数组赋值验证
- 直接对比
sb和sb_midi的列数据:比如打印sb[:,1]和sb_midi[:,对应目标列]的前20个元素,确认置换赋值是否真正生效。
- 直接对比
内容的提问来源于stack exchange,提问作者Alex Used
相关产品推荐
相关产品推荐

