一般情况下,图像的加密和解密过程是通过按位异或运算实现的。将原始图像与密钥图像进行按位异或,可以实现加密,将加密后的图像与密钥图像再进行按位异或可以实现解密过程。
一、基本原理
按位异或运算的基本规则如下表:
算子1 | 算子2 | 结果 | 规则 |
0 | 0 | 0 | xor(0, 0) = 0 |
0 | 1 | 1 | xor(0, 1) = 1 |
1 | 0 | 1 | xor(1, 0) = 1 |
1 | 1 | 0 | xor(1, 1) = 0 |
8位灰度图像中,每一个像素由8位二进制表示,其范围在[0, 255]之间。下表阐述了利用密钥178,对像素值216加密和解密过程。
加密过程 | 运算 | 说明 | 二进制 | 十进制 |
bit_xor | 明文 | 1101 1000 | 216 | |
密钥 | 1011 0010 | 178 | ||
运算结果 | 密文 | 0110 1010 | 106 |
解密过程 | 运算 | 说明 | 二进制 | 十进制 |
bit_xor | 密文 | 0110 1010 | 106 | |
密钥 | 1011 0010 | 178 | ||
运算结果 | 明文 | 1101 1000 | 216 |
假设有需要加密的原始图像A,其像素值为:
172 | 168 | 56 |
22 | 89 | 40 |
27 | 48 | 119 |
图像A的二进制表示为AB,其像素值为:
1010 1100 | 1010 1000 | 0011 1000 |
0001 0110 | 0101 1001 | 0010 1000 |
0001 1011 | 0011 0000 | 0111 0111 |
加密密钥图像为K,其像素值为:
132 | 177 | 156 |
152 | 56 | 70 |
26 | 99 | 162 |
图像K的二进制表示为KB,其像素值为:
1000 0100 | 1011 0001 | 1001 1100 |
1001 1000 | 0011 1000 | 0100 0110 |
0001 1010 | 0110 0011 | 1010 0010 |
接下来实现图像AB和图像KB的按位异或运算得到AKB:
0010 1000 | 0001 1000 | 1010 0100 |
1000 1110 | 0110 0001 | 0110 1110 |
0000 0001 | 0101 0011 | 1101 0101 |
图像AKB转换为十进制图像AK:
40 | 24 | 164 |
142 | 97 | 110 |
1 | 83 | 213 |
可以看出将A图像加密后的图像AK已经发生了本质的变换,下面将AKB图像继续和密钥图像KB进行按位异或运算,得到图像XB:
1010 1100 | 1010 1000 | 0011 1000 |
0001 0110 | 0101 1001 | 0010 1000 |
0001 1011 | 0011 0000 | 0111 0111 |
将图像XB转换为十进制图像X:
172 | 168 | 56 |
22 | 89 | 40 |
27 | 48 | 119 |
可以发现,x图像和原来的图像A完全一致。该过程详细解释了8位图像的加密和解密过程。在实际应用中,收发双方应该事先的规定好密钥图像,发送方利用密钥图像将图片加密,将密文发给接收方,然后接收方接到密文,然后用密钥进行解密,最终得到原始图像。
二、代码实现
import cv2
import numpy as np
demo = cv2.imread("demo.jpg", 0)
r, c = demo.shape
key = np.random.randint(0, 256, size=(r, c), dtype=np.uint8) # 生成随机的密钥图像
cv2.imshow("demo", demo) # 显示原始图像
cv2.imshow("key", key) # 显示密钥图像
encryption = cv2.bitwise_xor(demo, key) # 加密
decryption = cv2.bitwise_xor(encryption, key) # 解密
cv2.imshow("encryption", encryption) # 显示密文图像
cv2.imshow("decryption", decryption) # 显示解密后的图像
cv2.waitKey(-1)
cv2.destroyAllWindows()
原始图像 密钥图像
密文图像 解密后图像