前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:如何给中文加密?

一日一技:如何给中文加密?

作者头像
青南
发布2020-03-26 11:43:31
5.1K0
发布2020-03-26 11:43:31
举报
文章被收录于专栏:未闻Code
在看各类加密文章的时候,你一般会看到作者总是使用对一个数字进行加密来举例。但是现实生活中,我们使用中文进行交流,那如何对中文进行加密呢?

在文章《别怕,我们的聊天消息,没人能偷看》中,我们对一段中文进行加密,有这样一个段代码:

代码语言:javascript
复制
msg = '今晚8点,老地方碰头'
encryptd_msg = rsa.encrypt(msg.encode(), public_key)

其中,msg.encode()把中文信息转换为了 bytes 型数据。我们来看一下这段 bytes 型数据型数据长什么样:

看起来一长串的十六进制值,似乎很难读懂。不过没关系,我们把这个 bytes 型的数据再转成列表看看:

这就变成了一个包含数字的列表。并且,如果你多次测试,你会发现,这些数字的范围是0-255.恰好对应了十六进制的00ff

现在我们就可以对数字进行加密了。由于00-ff对应了8位的二进制数,所以我们假设现在密钥是45,它的二进制值为00101101,我们把这个列表里面的每一个数字对45取异或,得到一个新的数字列表:

注意,这里实际上当你使用 for 循环展开时,不用提前把 bytes 型字符串转换为列表,直接循环展开效果一致,如下图所示:

现在,我们再来把这段包含数字的列表转换为 bytes 型数据:

需要注意的是,并非所有 bytes 都能重新转换回字符串,现在新的 bytes 型密文就已经无法转换回去了:

所以,这个时候我们就需要使用 base64来把它编码为字符串:

base64的b64encode方法返回的也是一个 bytes 型数据,但是这次可以成功转回普通字符串了,并且普通字符串跟它的 bytes 形式完全一样:

现在,你可以把这一段密文通过公开的聊天软件发给你的朋友。

你的朋友只需要把整个过程反向操作,就能解析出正确的信息,我们来写一段代码:

代码语言:javascript
复制
import base64
code = 'yZany7S3FcqvlMKRocWtrMixncu7lMqPnciJmQ=='

encrypted_msg = base64.b64decode(code.encode())

bytes_list = [x ^ 45 for x in encrypted_msg]

msg_bytes = bytes(bytes_list)
msg = msg_bytes.decode()
print(msg)

运行效果如下图所示:

成功解密。

其中的数字45就是密码。异或操作有一个性质:

代码语言:javascript
复制
A xor B xor B = A

一个数字A,先对另一个数字 B 执行异或操作得到密文 C,然后 C 再对 B 进行一次异或操作,又能还原为 A。

我们正是使用了这样一个性质,实现了加密和解密。

可能有同学会问,为什么这里你选择异或,而不是列表里面的所有数字同时乘以或者加上某个数来加密呢?这是因为,如果要把一个包含数字的列表转成 bytes 型数据,那么列表里面的所有数字都必须在0-255的范围内,否则就会导致报错,如下图所示:

我们无法保证加法或者乘法执行以后的数字仍然在0-255这个范围内,但用其他复杂的算法又不一定可逆。所以我们选择了异或算法。

从本文可以看到,对中文进行加密,本质上还是对数字加密。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档