图像加密-DNA运算的图像加密学习

图像加密-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] # 红色通道

# 找到最大的长宽
# 调整图像大小为16的倍数
max_dim = max(height, width)
max_dim = (max_dim + 15) // 16 * 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)
# 保存不同通道的图片(选)
# cv2.imwrite('lena_blue_channel.bmp', padded_I1)
# cv2.imwrite('lena_green_channel.bmp', padded_I2)
# cv2.imwrite('lena_red_channel.bmp', padded_I3)
1.1
l_red_channel
l_blue_channel
l_green_channel

相加

当两张图像,各自对应的像素相加,就有可能超过八位,所以在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
# 导入numpy库,重命名为np
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 # 只保留低8位,相当于取模256

# 输出二进制表示的结果
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
# 导入numpy库,重命名为np
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:

l_blue_channel

原图2:

2_Henon_R

得到:

Result (Addition)

代码:

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):

# 进行二进制相减
# 由于可能存在负数,需要确保结果在 [0, 255] 范围内
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)

# 进行二进制相加和相减
# 原图1和原图2进行相加
result_add = binary_addition(img1, img2)
# 结果图-原图2=原图1
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()

然后有意思的是出现了:

原图:

l_blue_channel

但是我异或、同或后的结果:

2

很诡异,但是其实可以看出来,得到的图像,和原图像的差别,只是黑白值互换了。

检查代码,发现确实是因为自己同或的顺序放反了。再次试验后发现,同或再同或,才能得到原图像,自己是对他进行异或了,所以得不到原图像。

但是其实通过异或实验,我们也能得到大致的图像信息,说明同或、异或本身之间相关性很高。

更改代码:

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()

实验成功:

tonghuo
tonghuo1

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) # 转换为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()

原图:

image_gray

结果图:

binary_image

图像加密-DNA运算的图像加密学习
https://yelelalearn.github.io/2024/04/10/图像加密-DNA运算的图像加密学习/
作者
Yelearn
发布于
2024年4月10日
更新于
2024年4月10日
许可协议