-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrypto_mosaic.py
More file actions
259 lines (208 loc) · 8.56 KB
/
Copy pathcrypto_mosaic.py
File metadata and controls
259 lines (208 loc) · 8.56 KB
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
from PIL import Image
import random
import numpy as np
def generate_colored_noise(width, height):
"""
生成彩色噪声图像
参数:
width: 图像宽度
height: 图像高度
返回:
noise_img: 彩色噪声图像
"""
# 创建随机噪声数组
noise_array = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8)
noise_img = Image.fromarray(noise_array)
return noise_img
def xor_operation(pixel1, pixel2):
"""
对两个像素进行异或操作
参数:
pixel1: 第一个像素 (R, G, B)
pixel2: 第二个像素 (R, G, B)
返回:
异或后的像素 (R, G, B)
"""
return tuple(p1 ^ p2 for p1, p2 in zip(pixel1, pixel2))
def block_shuffle_with_noise(image_path, block_size=32):
"""
块状打乱图像并与噪声混合,生成三张输出图像
参数:
image_path: 原始图像路径
block_size: 块大小
返回:
output_img: 混合后的输出图像
key_img: 灰度密钥图像
noise_img: 彩色噪声图像
"""
# 打开原始图像
original = Image.open(image_path).convert('RGB')
width, height = original.size
# 计算行列块数
cols = width // block_size
rows = height // block_size
# 调整图像尺寸以适应块大小
new_width = cols * block_size
new_height = rows * block_size
original = original.crop((0, 0, new_width, new_height))
# 创建打乱后的图像(先进行块打乱)
shuffled = Image.new('RGB', (new_width, new_height))
# 创建密钥图像(RGB模式)
key_img = Image.new('RGB', (cols, rows))
# 生成彩色噪声图像
noise_img = generate_colored_noise(new_width, new_height)
# 生成块索引列表并随机打乱
total_blocks = cols * rows
blocks = list(range(total_blocks))
random_blocks = blocks.copy()
random.shuffle(random_blocks)
# 处理每个块 - 先进行块打乱
key_pixels = key_img.load()
shuffled_pixels = shuffled.load()
original_pixels = original.load()
noise_pixels = noise_img.load()
for rand_idx in range(total_blocks):
orig_idx = random_blocks[rand_idx]
# 计算位置
orig_x = orig_idx % cols
orig_y = orig_idx // cols
rand_x = rand_idx % cols
rand_y = rand_idx // cols
# 在密钥图像中存储原始位置
key_pixels[rand_x, rand_y] = (orig_x, orig_y, 0)
# 复制像素块(只打乱,不混合噪声)
for i in range(block_size):
for j in range(block_size):
orig_pos_x = orig_x * block_size + i
orig_pos_y = orig_y * block_size + j
rand_pos_x = rand_x * block_size + i
rand_pos_y = rand_y * block_size + j
# 直接复制像素(先不打乱)
shuffled_pixels[rand_pos_x, rand_pos_y] = original_pixels[orig_pos_x, orig_pos_y]
# 创建最终输出图像(与噪声混合)
output_img = Image.new('RGB', (new_width, new_height))
output_pixels = output_img.load()
# 对整个图像进行噪声混合
for x in range(new_width):
for y in range(new_height):
shuffled_pixel = shuffled_pixels[x, y]
noise_pixel = noise_pixels[x, y]
# 异或混合
output_pixels[x, y] = xor_operation(shuffled_pixel, noise_pixel)
return output_img, key_img, noise_img
def restore_with_noise(output_path, key_path, noise_path, block_size=32):
"""
使用三张图片恢复原始图像
参数:
output_path: 混合输出图像路径
key_path: 密钥图像路径
noise_path: 噪声图像路径
block_size: 块大小
返回:
restored: 恢复后的原始图像
"""
# 打开所有图像
output_img = Image.open(output_path).convert('RGB')
key_img = Image.open(key_path).convert('RGB')
noise_img = Image.open(noise_path).convert('RGB')
width, height = output_img.size
key_width, key_height = key_img.size
# 计算行列块数
cols = width // block_size
rows = height // block_size
# 第一步:从输出图像中去除噪声
intermediate = Image.new('RGB', (width, height))
intermediate_pixels = intermediate.load()
output_pixels = output_img.load()
noise_pixels = noise_img.load()
for x in range(width):
for y in range(height):
output_pixel = output_pixels[x, y]
noise_pixel = noise_pixels[x, y]
# 异或操作去除噪声
intermediate_pixels[x, y] = xor_operation(output_pixel, noise_pixel)
# 第二步:根据密钥恢复块位置
restored = Image.new('RGB', (width, height))
restored_pixels = restored.load()
key_pixels = key_img.load()
for rand_x in range(key_width):
for rand_y in range(key_height):
# 从密钥获取原始位置
orig_x, orig_y, _ = key_pixels[rand_x, rand_y]
# 复制像素块到正确位置
for i in range(block_size):
for j in range(block_size):
orig_pos_x = orig_x * block_size + i
orig_pos_y = orig_y * block_size + j
rand_pos_x = rand_x * block_size + i
rand_pos_y = rand_y * block_size + j
# 从中间图像获取像素
intermediate_pixel = intermediate_pixels[rand_pos_x, rand_pos_y]
restored_pixels[orig_pos_x, orig_pos_y] = intermediate_pixel
return restored
# 更清晰的双重混合版本(可选)
def double_mix_block_shuffle(image_path, block_size=32):
"""
双重混合:块级混合 + 像素级混合
"""
original = Image.open(image_path).convert('RGB')
width, height = original.size
cols = width // block_size
rows = height // block_size
new_width = cols * block_size
new_height = rows * block_size
original = original.crop((0, 0, new_width, new_height))
# 生成噪声图像
noise_img = generate_colored_noise(new_width, new_height)
key_img = Image.new('RGB', (cols, rows))
output_img = Image.new('RGB', (new_width, new_height))
original_pixels = original.load()
noise_pixels = noise_img.load()
key_pixels = key_img.load()
output_pixels = output_img.load()
# 生成随机排列
total_blocks = cols * rows
blocks = list(range(total_blocks))
random_blocks = blocks.copy()
random.shuffle(random_blocks)
# 处理每个块
for rand_idx in range(total_blocks):
orig_idx = random_blocks[rand_idx]
orig_x = orig_idx % cols
orig_y = orig_idx // cols
rand_x = rand_idx % cols
rand_y = rand_idx // cols
# 存储映射关系
key_pixels[rand_x, rand_y] = (orig_x, orig_y, 0)
# 处理块内每个像素
for i in range(block_size):
for j in range(block_size):
orig_pos_x = orig_x * block_size + i
orig_pos_y = orig_y * block_size + j
rand_pos_x = rand_x * block_size + i
rand_pos_y = rand_y * block_size + j
# 获取原始像素和对应位置的噪声
orig_pixel = original_pixels[orig_pos_x, orig_pos_y]
noise_pixel = noise_pixels[rand_pos_x, rand_pos_y]
# 混合像素
mixed_pixel = xor_operation(orig_pixel, noise_pixel)
output_pixels[rand_pos_x, rand_pos_y] = mixed_pixel
return output_img, key_img, noise_img
# 使用示例
if __name__ == "__main__":
# 选择模式
flag = input("请选择模式(1-加密图片,2-解密图片): \n")
# 设置块大小
block_size = input("请输入块大小: \n")
if flag == "1":
print("块级和像素级同时混合中...")
output_img2, key_img2, noise_img2 = double_mix_block_shuffle("image.jpg", block_size)
output_img2.save("output_image_method.png")
key_img2.save("key_image.png")
noise_img2.save("noise_image.png")
elif flag == "2":
print("恢复中...")
# 恢复方法2的图像(使用相同的恢复函数)
restored_img2 = restore_with_noise("output_image_method.png", "key_image.png", "noise_image.png", block_size)
restored_img2.save("restored_image_method.png")
print("所有图像生成和恢复完成!")