Python:对图片进行加密解密极其简单的方法

该方法对图片进行加密的原理是基于像素的置换,对于python最好是使用PIL库,使用opencv来做的话,由于cv.imread()方法读取出来的NumPy数组的结构没有那么直观,写起来相比来说更麻烦一些。

该方法的具体实现很简单,就是用PIL读取某一图片,就能获取包含大量元组构成的列表。先用random.seed()设置种子(就相当于密码),再用random.shuffle()打乱列表,最后用putdata()和save()就能获得加密过后的图片。具体代码如下:

from PIL import Image
import random

image_path = "example.jpg"
image = Image.open(image_path)

pixels = list(image.getdata())
#设置密码为1234
random.seed(1234)

random.shuffle(pixels)

image.putdata(pixels)

image.save("shuffled_pixels.jpg")

解密的时候我们只需要先创建一个从0到图片的总像素的数量的有序连续数的列表,再用相同的随机数种子对该列表进行打乱。因为对于同样长度的列表random.shuffle()是以同样的方式进行打乱的,所以该被打乱的连续数列表中的每一个数就相当于被打乱的像素列表的每一个元组的索引,比如说打乱后的连续数列表的第一个数是42,那么相应的被打乱的像素列表的第一个元素的原始索引应该是42。根据该列表就能使被打乱的图片的像素回归原来的位置。

from PIL import Image
import random


#获取图片的宽度和高度
pixel_height = image.height
pixel_width = image.width

shufflelist = list(range(pixel_height * pixel_width))

random.seed(1234)

random.shuffle(shufflelist)

newpixels = [0] * (pixel_height * pixel_width)

for i in range(pixel_height * pixel_width):
    index = shufflelist[i]
    newpixels[index] = pixels[i]

image.putdata(newpixels)

image.save("fix.jpg")

此外,从理论上说该方法可以支持有各种符号的密码,因为我们只需要将其转化为unicode编码并以此为随机数种子就行了。

string = "源神,启动!"
password = 0

for char in string:
    #将字符转换为Unicode编码
    unicode_code = ord(char)
    password += unicode_code

当然这也意味着该方法密码可能有好几个:1.可能有另一个随机数种子能以相同的方式打乱列表。2.可能有好几种密码的形式。

这个图像加密的方法想都不用想肯定是不安全,但个人觉得玩玩还不错。 

完整示例代码:

from PIL import Image
import random

image_path = "example.jpg"
image = Image.open(image_path)

pixels = list(image.getdata())

pixel_height = image.height
pixel_width = image.width

print(pixels[0:10])

random.seed(1234)

random.shuffle(pixels)

image.putdata(pixels)

image.save("shuffled_pixels.jpg")

shufflelist = list(range(pixel_height * pixel_width))

random.seed(1234)

random.shuffle(shufflelist)

newpixels = [0] * (pixel_height * pixel_width)

for i in range(pixel_height * pixel_width):
    index = shufflelist[i]
    newpixels[index] = pixels[i]

print(pixels[0:10])
print(newpixels[0:10])

image.putdata(newpixels)

image.save("fix.jpg")

image_path2 = "shuffled_pixels.jpg"
image2 = Image.open(image_path2)

pixels2 = list(image2.getdata())

newpixels2 = [0] * (pixel_height * pixel_width)

for i in range(pixel_height * pixel_width):
    index = shufflelist[i]
    newpixels2[index] = pixels2[i]

image2.putdata(newpixels2)

image2.save("fix2.jpg")

加密解密的效果如下所示:

                                                                ——加密前——

                                                                ——加密后—— 

                                                                 ——解密后——

然而在实际的操作中,PIL保存打乱后的图片会损坏像素信息,当你再读取的时候并解密的图片一般会呈黑白色并带一点原始图片的总色调。

以这张图片为例,解密后的图片带有一层粉色的感觉,这张图片算是比较明显还带点非黑白的颜色,有些图片直接看上去几乎完全就是黑白的但实际上用PIL读取得来的列表还是带RGB信息的元组。此外解密后的图片也多出了一些噪点。

这些打乱后的加密图像的图像大小也剧增,从原来的764K变成了5.39MB,直接由打乱后的像素列表解密得来的图像还是保持764K,但由打乱后的图像读取后得来的像素列表再解密得来的图像大小为1.93MB。

(笔者很菜,完全不知道为什么,只是做做简单的分享。。。也希望有大佬能解惑)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值