贪心学院 Demo1 - 情报密码锁

导读:
demo内容来源网课贪心科技AI学社的网课《人工智能Python编程特训营》
本篇博客的主要内容是简单的加密解密,主要是利用了编码。
先附上了我自己写的中英文加密的demo,将加密规则保存到了本地。
然后附上了课堂上的几个小案例。
还有随手写的一个爬取常见中文的小爬虫。

作业

自己写一个加密程序,能够加密的内容是英文和汉字。同时加密并且解密
就是说,一段话中既有中文又有英文,标点符号不用处理。
加密规则,获取ascii码数字,中间用|分割

我没有严格按照这个作业来,因为作业是源自课堂的demo。我最后实现的是一个中英文包括常用英文字符的加密解密,并把密码本存到本地,加密规则见后文。
其实这个作业意义不是很大,因为正常加密不会这么用,之后会给出现在的比较常用的加密函数。

实现效果如下:

其实代码很简单,主要是了解了一下关于ASCII和Unicode编码规则。
有两个重要的函数ord()chr()可以分别将字符转化为Unicode编码和将Unicode编码转化为字符。
先定义我们加密的信息范围,一个是ASCII从33-126的可显示字符,包含了英文、英文标点、数字,但是这里不包含中文的标点符号。另一个是4E00-9FA5是Unicode编码中常用汉字的范围,当然还有其他不常用的汉字,但是这个是个demo就没必要去做了。

# ASCII有符号显示的从33 - 126
ASCII_START = 33
ASCII_END = 126
# 常用汉字的Unicode从4E00 - 9FA5
HAN_START = int('0x4E00', 16)  # 19968
HAN_END = int('0x9FA5', 16)  # 40869

ord()函数在Python3之后就支持Unicode(万国码)而不仅仅支持ASCII,虽然0-127是一样的,但是127-255的扩展ASCII码和Unicode是不同的。

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

我这里加密的想法是先将所有需要转换的字符存储到一个密码本中,然后用下标去当做密码,课程上老师的做法也是这么做的,但是他用到了|作为分隔符,但是我们这个demo中|是可以进行加密的,所以不合适。

DEMO的加密规则

因此我就决定用两个密码本,读取一个句子,在A密码本中找到下标,然后下标在B密码本的文字就是原来文字的加密状态。解密同理,将加密后的文字在B密码本中找到下标,下标对应的文字在A密码本中的文字就是原来文字的加密状态。

因此我们用init_codebook_A()生成A密码本,用init_codebook_B()函数生成B密码本。

import random

# 生成初始状态的密码本A
def init_codebook_A():
    codebook_A = []
    # 将ASCII加入密码本
    for i in range(ASCII_START, ASCII_END + 1):
        codebook_A += chr(i)
    # 将汉字加入密码本
    for i in range(HAN_START, HAN_END + 1):
        codebook_A += chr(i)
    print("A密码本长度:" + str(len(codebook_A)))
    print(codebook_A)
    save_codebook("codebook_A", codebook_A)  # 保存密码本
    return codebook_A

# 生成随即打乱后的密码本B
def init_codebook_B(codebook):
    random.shuffle(codebook)  # 随机打乱顺序
    print(codebook)
    save_codebook("codebook_B", codebook)  # 保存密码本
    return codebook

在生成密码本的时候我们必须将密码本也保存下来,这里使用了空格作为保存进文本的状态,因为空格没有在我们的加密范围内。

# 保存密码本
def save_codebook(filename, codebook):
    with codecs.open(filename + '.txt', 'w', 'utf-8') as f:
        for code in codebook:
            code = code + ' '
            f.write(code, )  # 遍历循环,写入文件
    print("保存密码本" + filename + "成功")

# 加载密码本
def load_codebook():
    with codecs.open('codebook_A.txt', 'r', 'utf-8') as f_A:  # 读取A密码本
        codebook_A = f_A.read().split(" ")
        codebook_A.remove("")
        print("A密码本长度:" + str(len(codebook_A)))
    with codecs.open('codebook_B.txt', 'r', 'utf-8') as f_B:  # 读取B密码本
        codebook_B = f_B.read().split(" ")
        codebook_B.remove("")
        print("B密码本长度:" + str(len(codebook_A)))
    print("加载密码本成功")
    return codebook_A, codebook_B

加密和解密的程序写法类似,本质上是一个程序,只是加密和解密的过程传入的值是不一样的。

# 加密/解密,传入文本信息和两个密码本
# 第一个密码本获取索引,第二个密码本根据第一个密码本的索引获取字符
def code_process(message, codebook_first, codebook_second):
    coded_message = ""
    for char in message:
        if char in codebook_first:
            index = codebook_first.index(char)
            # print(index)
            coded_char = codebook_second[index]
            # print(coded_char)
            coded_message += coded_char
        else:
            coded_message += char
    return coded_message

最后我们直接调用上面封装好的函数就可以了。、
首先是初始化A和B两个密码本,这时候两个密码本已经写入本地了。
接着是加载密码本。
然后就可以输入文字,同时给出了解密后的语句和解密后的语句。

import os

# 先判断文件是否存在,若不存在就创建密码本,若存在就用以前的密码本就好了
if os.path.exists("codebook_A.txt") and os.path.exists("codebook_B.txt"):
    pass
else:
    codebook_A = init_codebook_A()
    codebook_B = init_codebook_B(codebook_A)

new_codebook_A, new_codebook_B = load_codebook()
while (True):  # 多输入
    message = input("请输入文本信息:")
    coded_message = code_process(message, new_codebook_A, new_codebook_B)
    print("加密: " + coded_message)
    print("解密: " + code_process(coded_message, new_codebook_B, new_codebook_A))

其实这是一个挺无聊的DEMO。大家可以随便看看。搞定了作业之后,再来回顾下课堂内容,然后再讨论一下现在的加密技术。

回顾课堂

利用对称加密的方法对英文进行加密,大致的加密规则就是利用ASCII的移位,大小写英文字母循环移动13位进行加密。直接贴一下代码,具体的实现很好懂,就不解释了,也没有封装成函数。

# 输入一段话
message = input("please input your message >>>>")

# 定义一个结果,这个结果加密后的结果
result = ""
for char in message:
    value = ord(char)
    # 大写ascii 65 - 90
    # 小写ascii 97 - 122
    if 64 < value < 78 or 96 < value < 110:
        result_char = chr(value + 13)
        result += result_char
    elif 77 < value < 91 or 109 < value < 123:
        result_char = chr(value - 13)
        result += result_char
    else:
        result += char
print("加密后的结果:" + result)

# 解密过程
after_result = ""
for r in result:
    value = ord(r)
    # 大写ascii 65 - 90
    # 小写ascii 97 - 122
    if 64 < value < 78 or 96 < value < 110:
        result_char = chr(value + 13)
        after_result += result_char
    elif 77 < value < 91 or 109 < value < 123:
        result_char = chr(value - 13)
        after_result += result_char
    else:
        after_result += r

print("解密后的结果:" + after_result)

另一个demo是利用爬虫爬取3500个常用字进行加密。爬取网站上3500个汉字,利用正则表达式获取所有的汉字并存到数组。具体的代码解释都在注释里面,这里只做记录。

import requests
import re
# 抓取网页源代码
html_result = requests.get("https://www.zdic.net/zd/zb/cc1/")
# 书写正则表达式来获取网页源代码中的所有汉字
reg = "href='//www.greatytc.com/hans/(.*)' "
hans_list = re.findall(reg, html_result.text)
print(hans_list)

# 加密的字符串
input_message = "我来贪心学院学习"
# 我要存储加密完成的字符串
result = ""

# 加密规则
# 到hans_list 这个变量中寻找我输入的汉字,并将其位置取出来,作为加密后的编号
# 并且我们用|把这些组的数字分开
# 例子: 我爱中国  加密后 变成  29|30|12|24|

for hans in input_message:
    for index, element in enumerate(hans_list):
        if hans == element:
            # print(index)
            # print(element)
            result += str(index) + "|"
print("加密后的数据>>>"+result)

# 这里使用|将字符串进行分割,结果是一个数组
index_list = result.split("|")
print(index_list)
# 移除数据中的空数据
index_list.remove("")
print(index_list)
#声明一个变量来存放解密后的结果
response_result = ""
# 遍历我的数组
for index in index_list:
    # 数组中的字符串转上int值
    int_index = int(index)
    response_result += hans_list[int_index]
print("解密后的数据>>>>"+response_result)

中文小爬虫

后来呢,我又觉得3500个词太少了,就写了一个小爬虫想爬取多一点的汉字(事实证明直接用ascii就可以了,这种做法特别愚蠢,但是可以扩展,比如之后可以做成汉字字典就需要爬虫的方法)。同样,代码部分就不解释了,应该都看得懂,这里也只是用来保存。

import requests
from bs4 import BeautifulSoup
import codecs
import time
import re

# 该网站http://www.cnpoem.net/hz/一共收录了16159个汉字
# 获取共41页的url
def getURL():
    # 抓取网页源代码
    url_head = "http://www.cnpoem.net/hz/index.asp?page="
    url_end = "&cate=&key="
    # 定义数据存储所有URL
    url_list = []
    for i in range(41):
        url = url_head + str(i + 1) + url_end
        print(url)
        url_list.append(url)
    # print(len(url_list))
    # print(url_list)
    return url_list


# 传入URL,解析获取所有网页中所有汉字,并存入数组
def HtmlParser(url):
    html_result = requests.get(url)
    html_result.encoding = 'gbk'
    soup = BeautifulSoup(html_result.text, "html.parser")
    # print(soup.prettify())
    # 找到所有<a>标签
    for a in soup.find_all('a'):
        # 筛选所有<a>标签,当href中包含了detail时才是我们所需要的
        href = a.get("href")
        if (href.find("detail") >= 0):
            # print(href)
            word_list.append(a.text)  # 符合条件,补充在数组中
        # print(a.text)
    print(len(word_list))


# 保存数组到字典,采用追加的形式,如果不需要追加请确保本地无该文件
def saveDictionary(word_list):
    with codecs.open('ChineseDictionary.txt', 'a', 'utf-8') as f:
        for word in word_list:
            word = word + ' '
            f.write(word, )


# 从本地中加载字典存入本地数组
def loadDictionary():
    with codecs.open('ChineseDictionary.txt', 'r', 'utf-8') as f:
        f_read = f.read()
        word_list = f_read.split(" ")
        # print(word_list)
        word_list.remove("")
        print(f"字典内的个数:{len(word_list)}")
    return word_list


# 获取特定范围的URL,从1到41
def getSpecifyURL(start=1, end=41):
    for url in url_list[start - 1:end]:
        print(url)
        HtmlParser(url)

word_list = []  # 存储字集
url_list = getURL()
getSpecifyURL(1,3)
saveDictionary(word_list)
dict = loadDictionary()
print(dict)
print(len(dict))

以上就是一小点小的回顾,其实没什么用可以直接略过。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容