本文最后更新于 2024-04-10T23:56:11+08:00
图像加密-DNA加密-学习笔记
本文探究如何对图像二进制编码进行图像DNA加密。
密码学是用于保护数据安全的工具,从古老的凯撒密码到现代密码学,已经两千多年了。脱氧核糖核酸(DNA)是生物遗传物质,携带生命的遗传信息,自从Watson和Crick在1953年发现DNA之后,人们发现和发展了许多操作DNA的方法,同时也发现了DNA计算具有某些电子计算机无可比拟和替代的优越性。密码学和遗传学原本是毫不相关的两个学科。然而,随着现代科技的发展,近年来密码学和DNA开始走到了一起,并且关系越来越密切。
1994年美国南加州大学的Adleman成功地完成了用DNA计算来解决一个NP完全问题的实验,从而开创了DNA计算研究的新纪元。自此以后,越来越多的目光集中到对这门新兴学科的研究上来,其中包括了不少计算机专家和密码学界的知名人士,他们开始关注DNA计算对密码学及信息安全的影响,开始思考能否在DNA的领域里开辟密码的新天地。
DNA加密
目前常用的DNA加密,有多种方法,比如:先将图像转化成二进制码,在将他与另一图像,进行二进制相加、相减、同或、异或;
异或(xor),是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。
如果a、b两个值不相同,则异或结果为1。
如果a、b两个值相同,异或结果为0。
同或(XNOR),电路表示则为同或门,双输入若相同则输出为1,不同则输出为0。
举例子:
对于图像像素来说,每张图片有三种颜色,RGB三色(python的opencv在处理图像时,默认处理的顺序是BGR,要注意!!),0~255代表它的亮度。
每个颜色不同、亮度不同,颜色就不同;
我们使用八位二进制码,也就是00000000来表示亮度为0,11111111表示亮度为255——也就是最亮,0是最暗也就是全黑。
预处理
两图像相加,我们要先能保证,他们两张图片宽高长得一样,不然会没得减、或者没能全部覆盖我们要加密的图像。
预处理代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| import numpy as np import cv2 from matplotlib import pyplot as plt
image = cv2.imread('1.1.jpg')
height, width, _ = image.shape M = height N = width
I1 = image[:, :, 0] I2 = image[:, :, 1] I3 = image[:, :, 2]
max_dim = max(height, width) max_dim = (max_dim + 15) // 16 * 16
padded_I1 = np.zeros((max_dim, max_dim), dtype=np.uint8) padded_I2 = np.zeros((max_dim, max_dim), dtype=np.uint8) padded_I3 = np.zeros((max_dim, max_dim), dtype=np.uint8)
padded_I1[:M, :N] = I1 padded_I2[:M, :N] = I2 padded_I3[:M, :N] = I3
scale_factor = 0.5 padded_I1 = cv2.resize(padded_I1, None, fx=scale_factor, fy=scale_factor) padded_I2 = cv2.resize(padded_I2, None, fx=scale_factor, fy=scale_factor) padded_I3 = cv2.resize(padded_I3, None, fx=scale_factor, fy=scale_factor)
cv2.imshow('Bed Channel', padded_I1) cv2.imshow('Green Channel', padded_I2) cv2.imshow('Rlue Channel', padded_I3) cv2.waitKey(0) cv2.destroyAllWindows()
print(height,width,max_dim)
|
相加
当两张图像,各自对应的像素相加,就有可能超过八位,所以在python中,我们使用
result = result & 0xFF # 只保留低8位,相当于取模256
或者使用numpy库中的clip
方法:
result = np.clip(image1 - image2, 0, 255)
来对图像进行处理,防止溢出,说人话,担心出现255+1=256,超出我们定义的范围了,所以我们取模,让他重新回到我们定义的范围里。即:\((255+1)//256 = 0\),其中,\(//\)是取模。
取模256
代码演示如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import numpy as np
result1 = 231 result2 = 25
binary_num1 = int(bin(result1), 2) binary_num2 = int(bin(result2), 2)
result3 = binary_num1 + binary_num2
result3 = result3 & 0xFF
print(bin(result1),bin(result2),bin(result3),result3)
|
结果:
1
| 0b11100111 0b11001 0b0 0
|
使用clip方法
1 2 3 4 5 6 7 8 9 10 11 12
| import numpy as np
image1 = np.array([[100, 200, 1], [50, 220, 180],[50, 220, 180]], dtype=np.uint8) image2 = np.array([[80, 180, 255], [120, 190, 230],[50, 220, 180]], dtype=np.uint8)
result = np.clip(image1 + image2, 0, 255)
print(result)
|
结果:
1 2 3
| [[180 124 0] [170 154 154] [100 184 104]]
|
实验效果显示,两种方法都可以实现0~255的映射。
当我们把它用在图像上:
原图1:
原图2:
得到:
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import numpy as np import cv2
def binary_addition(img1, img2): result = np.clip(img1 + img2, 0, 255) return result
def binary_subtraction(img1, img2):
binary_result = np.clip(img1 - img2, 0, 255) return binary_result
img1 = cv2.imread('l_blue_channel.bmp', cv2.IMREAD_GRAYSCALE) img2 = cv2.imread('2_Henon_R.bmp', cv2.IMREAD_GRAYSCALE)
result_add = binary_addition(img1, img2)
result_sub = binary_subtraction(result_add, img2)
cv2.imshow('Original Image 1', img1) cv2.imshow('Original Image 2', img2) cv2.imshow('Result (Addition)', result_add) cv2.imshow('Result (Subtraction)', result_sub) cv2.waitKey(0) cv2.destroyAllWindows()
|
同或、异或
1 2
| cv2.bitwise_xor(block1, block2) cv2.bitwise_not(cv2.bitwise_xor(block1, block2))
|
测试代码:
1 2 3 4 5 6 7 8 9 10 11
| import cv2
image1 = cv2.imread('l_blue_channel.bmp', cv2.IMREAD_GRAYSCALE) image2 = cv2.imread('2_Henon_R.bmp', cv2.IMREAD_GRAYSCALE)
tonghuo = cv2.bitwise_xor(image1, image2) yihuo = cv2.bitwise_not(cv2.bitwise_xor(tonghuo, image2)) cv2.imshow("1",tonghuo) cv2.imshow("2",yihuo) cv2.waitKey(0) cv2.destroyAllWindows()
|
然后有意思的是出现了:
原图:
但是我异或、同或后的结果:
很诡异,但是其实可以看出来,得到的图像,和原图像的差别,只是黑白值互换了。
检查代码,发现确实是因为自己同或的顺序放反了。再次试验后发现,同或再同或,才能得到原图像,自己是对他进行异或了,所以得不到原图像。
但是其实通过异或实验,我们也能得到大致的图像信息,说明同或、异或本身之间相关性很高。
更改代码:
1 2 3 4 5 6 7 8 9 10 11
| import cv2
image1 = cv2.imread('l_blue_channel.bmp', cv2.IMREAD_GRAYSCALE) image2 = cv2.imread('2_Henon_R.bmp', cv2.IMREAD_GRAYSCALE)
tonghuo = cv2.bitwise_xor(image1, image2) tonghuo1 = cv2.bitwise_xor(tonghuo, image2) cv2.imshow("1",tonghuo) cv2.imshow("2",tonghuo1) cv2.waitKey(0) cv2.destroyAllWindows()
|
实验成功:
0-1互换
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import numpy as np import cv2
image_gray = cv2.imread('l_blue_channel.bmp', cv2.IMREAD_GRAYSCALE)
height, width = image_gray.shape
binary_image = np.zeros_like(image_gray) for i in range(height): for j in range(width): pixel_binary = bin(image_gray[i, j])[2:].zfill(8) inverted_binary = ''.join(['1' if bit == '0' else '0' for bit in pixel_binary]) binary_image[i, j] = int(inverted_binary, 2)
cv2.imshow('Inverted Binary Image', binary_image) cv2.imshow('image_gray Image', image_gray) cv2.waitKey(0) cv2.destroyAllWindows()
|
原图:
结果图: