# 信息隐藏技术 **Repository Path**: heizicao/hiding-technology ## Basic Information - **Project Name**: 信息隐藏技术 - **Description**: 使用DCT的算法使信息隐藏于图片(不算可逆隐藏,只要用DCT就不是了),可将信息进行加密。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2020-09-01 - **Last Updated**: 2024-11-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 信息隐藏技术 #### 介绍 使用DCT的算法使信息隐藏于图片(不算可逆隐藏,只要用DCT就不是了),可将信息进行加密。 #### 软件架构 利用PYTHON进行编程及仿真,仿真内容为基于DCT算法的可逆信息隐藏技术的应用实例。根据课堂上所学习的内容,对信息进行输入,提取并测试其一致性,鲁棒性。 #### 使用说明 1. 准备好一张bmp格式的图片,用PYTHON将这张图片读取到环境中 2. 此算法要求图片为灰度图片,故我们需要将图片转为灰度图片显示。可以采用如下表达式:img_gray = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE) #### 展示 在写入信息界面过程中: 内容可以输入中文文字、字母、数字任意组合 密码也是,可以自己输入想输入的密码,可以是文字、字母、数字任意组合 ![输入图片说明](https://images.gitee.com/uploads/images/2020/0901/145738_38b10492_5448858.png "3525.png") 点击左上角文件菜单,可以选择到读取信息界面,或者选择退出该程序 ![输入图片说明](https://images.gitee.com/uploads/images/2020/0901/145759_aa66dadf_5448858.png "253252.png") 读取信息页面: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0901/145837_4a95fb5b_5448858.png "235235.png") ![输入图片说明](https://images.gitee.com/uploads/images/2020/0901/145904_44e725b0_5448858.png "535.png") #### 写入算法: # 数组转字符串 def bitseq2str(msgbits): binstr = ''.join([bin(b & 1).strip('0b').zfill(1) for b in msgbits]) str = np.zeros(np.int(len(msgbits) / 8)).astype(np.int) for i in range(0, len(str)): str[i] = int('0b' + binstr[(8 * i):(8 * (i + 1))], 2) return bytes(str.astype(np.int8)).decode() def getBit(num, bit_idx): ''' 从num中获取由bit_idx指定的给定位 ''' return (num & (1 << (8 - bit_idx))) >> (8 - bit_idx) # 提取信息 def dct_extract(img_marked, len_msg, seed=2020): "An illustration of data extraction to the previous embedding," " img_marked - of grayscale" " seed - the password for decryption" if len(img_marked.shape) > 2: print("图像应为灰度img") return img_marked N = 8 height, width = img_marked.shape msg_embedded = '' cnt = 0 r0, c0 = 2, 3 for row in np.arange(0, height - N, N): if cnt >= len_msg: break for col in np.arange(0, width - N, N): if cnt >= len_msg: break # 在1对DCT系数中嵌入一位 block = np.array(img_marked[row:(row + N), col:(col + N)], np.float32) block_dct = cv2.dct(block) msg_embedded += ('1' if block_dct[r0, c0] > block_dct[c0, r0] else '0') cnt += 1 bits_extracted = [np.uint8(c) for c in msg_embedded] print('提取:', bits_extracted) random.seed(seed) s = [random.randint(0, 1) for i in range(len_msg)] msgbits = np.bitwise_xor(bits_extracted, np.uint8(s)) msg = bitseq2str(msgbits) return msg #### 读取算法: def getBit(num, bit_idx): ''' 从num中获取由bit_idx指定的给定位 ''' return (num & (1 << (8 - bit_idx))) >> (8 - bit_idx) # 写入信息 def dct_embed(img_gray, msg, seed=2020): "An illustration of how data are embedded in pair-wise DCT coefficients," " img_gray - of grayscale" " msg - the to be embedded msg composed of 0 and 1 only" " seed - the encryption password" if len(img_gray.shape) > 2: print("图像应为灰度img") return img_gray # Step 1: 检查嵌入容量 msg2embed = str2bitseq(msg) len_msg = len(msg2embed) # print(len_msg, msg2embed) # EC: embedding capacity 嵌入容量 # 每个N×N块中隐藏1位 N = 8 height, width = img_gray.shape EC = np.int((height) * (width) / N / N) if EC < len_msg: print('嵌入容量 {} 不够'.format(EC)) return img_gray # 加密 msg2embed random.seed(seed) s = [random.randint(0, 1) for i in range(len_msg)] bits2embed = np.bitwise_xor(msg2embed, np.uint8(s)) print('嵌入:', bits2embed) # Step 2 通过成对DCT排序嵌入数据 # 嵌入从右下角开始 img_marked = img_gray.copy() height, width = img_marked.shape cnt = 0 delta = 10 r0, c0 = 2, 3 for row in np.arange(0, height - N, N): if cnt >= len_msg: break for col in np.arange(0, width - N, N): if cnt >= len_msg: break # 在1对DCT系数中嵌入一位 block = np.array(img_marked[row:(row + N), col:(col + N)], np.float32) block_dct = cv2.dct(block) a, b = (block_dct[r0, c0], block_dct[c0, r0]) if block_dct[r0, c0] > block_dct[c0, r0] else ( block_dct[c0, r0], block_dct[r0, c0]) a += delta b -= delta block_dct[r0, c0] = (a if bits2embed[cnt] == 1 else b) block_dct[c0, r0] = (b if bits2embed[cnt] == 1 else a) cnt += 1 img_marked[row:(row + N), col:(col + N)] = np.array(cv2.idct(block_dct), np.uint8) return img_marked, len_msg