2023年杭州北斗聯(lián)盟高二期中卷第17題解析
說在前面:
選拔人才是考試的重要目的,不但要考查學(xué)生的學(xué)業(yè)水平,還要考查學(xué)生的核心素養(yǎng),篩選出具有較高信息素養(yǎng)和計(jì)算思維的優(yōu)秀學(xué)生。壓軸題就是區(qū)分普通學(xué)生和優(yōu)秀學(xué)生的主戰(zhàn)場(chǎng),也成為考驗(yàn)命題人業(yè)務(wù)水平和控場(chǎng)能力的試金石。 《2023年杭州北斗聯(lián)盟高二期中卷》第17題考查了“加密和解密問題”,題目綜合性強(qiáng),問題設(shè)置巧妙,難度逐次增加,既給了中等生得分的機(jī)會(huì),又為優(yōu)等生創(chuàng)造了展示才華的空間,是一道具備“壓軸題”特性的好題目。 當(dāng)然,如果單純從解決問題的角度來看,題目雜糅了進(jìn)制轉(zhuǎn)換和直接對(duì)十進(jìn)制數(shù)進(jìn)行循環(huán)移位處理兩種方法,而且沒有嚴(yán)格按照算法描述來編寫代碼,人為增加難度來提高區(qū)分度,顯得不夠“自然”。 筆者對(duì)原題代碼進(jìn)行了一些剖析,并給出了另一種更為貼合算法描述的代碼實(shí)現(xiàn)。另外,在拓展思考中,筆者采用兩種不同算法,分別實(shí)現(xiàn)了加密和解密功能。 由于筆者水平有限,理解可能有些不到位,若存在錯(cuò)誤或偏激之處,敬請(qǐng)各位老師批評(píng)指正。題目及解析:
密碼的文本(密碼的組成都為 ASCII 字符),一旦文本內(nèi)容泄露將造成巨大的損失。于是,小運(yùn)自編了一套加密方法,對(duì)明文(原密碼)的每個(gè)字符進(jìn)行下列加密處理: (1)將該字符的ASCII碼轉(zhuǎn)換成8位二進(jìn)制數(shù)(不足8位的,高位補(bǔ)上相應(yīng)數(shù)量的0); (2)將上述8位二進(jìn)制循環(huán)左移3次(移出的數(shù)位放在最右邊);(3)將上述處理后的8位二進(jìn)制數(shù)依次取反(1變0,0變1);
(4)最后將這8位二進(jìn)制分成左右兩個(gè)4位二進(jìn)制數(shù),分別轉(zhuǎn)換成十進(jìn)制數(shù),然后從下表中取出相應(yīng)的字符作為新密碼。

例如, 密碼為小寫字母 "a", 通過上述加密算法加密后的密文是“ Tf ” , 加密過程如下:
“a的ASCII碼:01100001”?“循環(huán)左移3次:00001011”?“逐位取反:11110100”?“轉(zhuǎn)換為兩個(gè)十進(jìn)制數(shù):15,4”?“得到密文:Tf”。
(1)如果明文為小寫字母“c”,則加密后的密文是______。 (2)根據(jù)加密的規(guī)律,小運(yùn)用Python編寫了一個(gè)程序,用于將加密后的新密碼進(jìn)行解密得到原密碼,程序如下所示,請(qǐng)?jiān)趧澗€處填寫正確的代碼:考查知識(shí)點(diǎn):def DtoBqf(n): #DtoBqf函數(shù)實(shí)現(xiàn)將十進(jìn)制數(shù)轉(zhuǎn)為4位二進(jìn)制數(shù)并取反s = ""for i in range(4):s = str(1 - n % 2) + sn = n // 2return s
def BtoD(s): #BtoD函數(shù)實(shí)現(xiàn)將二進(jìn)制數(shù)轉(zhuǎn)為十進(jìn)制數(shù)n = 0for i in s:①return n
miwen = input("輸入密文:")key = "WgQ#f02y*?ScApxT"a=[]; b=[]; n=0; ans=""; mingwen=""for i in miwen:for j in range(len(key)):if i == key[j]:a.append(j)②for i in range(len(a)):ans += DtoBqf(a[i])if i % 2 == 1:b.append(BtoD(ans))ans = ""for i in range(len(b)):③mingwen = mingwen + chr(n)print("明文為:",mingwen)
加密解密、進(jìn)制轉(zhuǎn)換算法、循環(huán)移位算法、自定義函數(shù)。要求學(xué)生理解加密解密基本思路和進(jìn)制轉(zhuǎn)換算法、熟悉字符串和列表基本操作。
解析: (1)模仿題面給出的示例,可知小寫字母"c"的加密過程如下: “c的ASCII碼:01100011”?“循環(huán)左移3次:00011011”?“逐位取反:11100100”?“轉(zhuǎn)換為兩個(gè)十進(jìn)制數(shù):14,4”?“得到密文:xf”。 (2)BtoD函數(shù)實(shí)現(xiàn)將二進(jìn)制數(shù)轉(zhuǎn)為十進(jìn)制數(shù),采用了經(jīng)典的累乘相加算法,故第①空答案為n=n*2+int(i)。 第②空所在二重循環(huán)的作用是遍歷密文字符串,找到每一個(gè)加密字符對(duì)應(yīng)的十進(jìn)制值(即在key中的下標(biāo))。當(dāng)在key中找到字符i時(shí),將其下標(biāo)j存儲(chǔ)到列表a中,并跳出循環(huán),故第②空答案為break。當(dāng)然,找到字符后不跳出循環(huán)也不是不可以,但效率就低了,不符合一般習(xí)慣。 初看第③空的答案好像是n=b[i]。但如果這樣做就上當(dāng)了。因?yàn)榱斜韇中存儲(chǔ)的是尚未循環(huán)移位的二進(jìn)制數(shù)對(duì)應(yīng)的整數(shù),需要對(duì)其做循環(huán)移位操作后才能調(diào)用chr函數(shù)生成對(duì)應(yīng)的字符。 那么如何直接對(duì)一個(gè)十進(jìn)制整數(shù)實(shí)現(xiàn)二進(jìn)制數(shù)循環(huán)移位的效果呢?這是本題的難點(diǎn)所在。 要想將二進(jìn)制數(shù)的低3位循環(huán)右移到高3位(即左移5位),需要先將二進(jìn)制數(shù)的低3位提取出來,方法是將十進(jìn)制數(shù)對(duì)8求余數(shù);然后再乘以32,實(shí)現(xiàn)左移5位的功能。最后加上原二進(jìn)制數(shù)的高5位即可。故第③空答案為n=b[i]%8*32+b[i]//8。 本題采用了巧妙的技巧來對(duì)十進(jìn)制數(shù)實(shí)現(xiàn)循環(huán)移位功能,提升了難度,增加了區(qū)分度。但解密算法的代碼實(shí)現(xiàn)與算法描述不完全一致,造成理解上的困難。筆者嘗試使用與加密算法恰好互逆的解密算法實(shí)現(xiàn),提高了代碼可讀性。參考代碼如下:
答案: (1 ) xf ( 2 分) (2) ① n=n*2+int(i) (2 分) ② break (2 分) ③ n=b[i]%8*32+b[i]//8 (2 分)#函數(shù)DtoBqf(n)和BtoD(s)與原題相同。代碼略。miwen = input("輸入密文:")dic_key = {'W': 0, 'g': 1, 'Q': 2, '#': 3, 'f': 4, '0': 5, '2': 6, 'y': 7, '*': 8, '?': 9, 'S': 10, 'c': 11, 'A': 12, 'p': 13, 'x': 14, 'T': 15}a=[]; b=[]; n=0; ans=""; mingwen=""for i in miwen:a.append(dic_key[i])for i in range(len(a)):ans += DtoBqf(a[i])if i % 2 == 1:ans = ans[-3:] + ans[:5]b.append(BtoD(ans))ans = ""for i in range(len(b)):n = b[i]mingwen = mingwen + chr(n)print("明文為:",mingwen)
拓展思考: 加密和解密算法經(jīng)典實(shí)用,綜合性強(qiáng),難度適當(dāng),是考試命題的熱點(diǎn)。此題給出加密算法,考查解密算法,是命題常用手法。在平時(shí)學(xué)習(xí)中,則應(yīng)更注重算法的實(shí)用性和典型性,要求學(xué)生同時(shí)掌握加密和解密算法的代碼實(shí)現(xiàn)。 筆者嘗試從處理二進(jìn)制數(shù)字串和直接處理整數(shù)兩種途徑,演示按位取反和循環(huán)移位的操作方法,供大家參考,歡迎各位老師批評(píng)指正。參考代碼如下: 算法一:先轉(zhuǎn)換成二進(jìn)制數(shù),再做按位取反和循環(huán)移位操作。
算法二:直接操作十進(jìn)制數(shù),通過求余數(shù)和整除運(yùn)算實(shí)現(xiàn)循環(huán)移位功能,通過異或運(yùn)算實(shí)現(xiàn)按位取反功能。def DtoBqf(d, n): #將十進(jìn)制數(shù)d轉(zhuǎn)為n位二進(jìn)制數(shù)并取反s = ""for i in range(n):s = str(1 - d % 2) + sd = d // 2return s
def BtoD(b): #將二進(jìn)制數(shù)b轉(zhuǎn)為十進(jìn)制數(shù)n = 0for i in b:n = n * 2 + int(i)return n
def encrypt(p_text): #將明文加密,返回密文key = "WgQ#f02y*?ScApxT" #加密密碼表c_text = ""for ch in p_text:b = DtoBqf(ord(ch), 8) #此條語句的作用是什么?b = b[3:] + b[:3] #此條語句的作用是什么?c_text += key[BtoD(b[0:4])] + key[BtoD(b[4:8])]return c_text #返回密文def decrypt(c_text): #將密文解密,返回明文dic_key = {'W': 0, 'g': 1, 'Q': 2, '#': 3, 'f': 4, '0': 5,'2': 6, 'y': 7, '*': 8, '?': 9, 'S': 10, 'c': 11,'A': 12, 'p': 13, 'x': 14, 'T': 15} #解密密碼表p_text = ""for i in range(0, len(c_text), 2): #2個(gè)密文字符對(duì)應(yīng)1個(gè)明文字符b = DtoBqf(dic_key[c_text[i]], 4) + DtoBqf(dic_key[c_text[i+1]], 4)b = b[-3:] + b[:-3] #此條語句的作用是什么?p_text += chr(BtoD(b)) #此條語句的作用是什么?return p_text #返回明文
mingwen = input("輸入明文:")#加密miwen = encrypt(mingwen)print("密文為:",miwen)#解密mingwen = decrypt(miwen)print("明文為:",mingwen)
寫在后面def encrypt(p_text): #將明文加密,返回密文key = "WgQ#f02y*?ScApxT" #加密密碼表c_text = ""for ch in p_text:d = ord(ch)d = d % 32 * 8 + d // 32 #此代碼段的作用是什么?d = d ^ 255 #此代碼段的作用是什么?c_text += key[d//16] + key[d%16]return c_text #返回密文def decrypt(c_text): #將密文解密,返回明文dic_key = {'W': 0, 'g': 1, 'Q': 2, '#': 3, 'f': 4, '0': 5,'2': 6, 'y': 7, '*': 8, '?': 9, 'S': 10, 'c': 11,'A': 12, 'p': 13, 'x': 14, 'T': 15} #解密密碼表p_text = ""for i in range(0, len(c_text), 2): #2個(gè)密文字符對(duì)應(yīng)1個(gè)明文字符d = dic_key[c_text[i]] * 16 + dic_key[c_text[i+1]]d = d ^ 255 #此代碼段的作用是什么?d = d % 8 * 32 + d // 8 #此代碼段的作用是什么?p_text += chr(d)return p_text #返回明文
mingwen = input("輸入明文:")#加密miwen = encrypt(mingwen)print("密文為:",miwen)#解密mingwen = decrypt(miwen)print("明文為:",mingwen)
為了保證解析的原創(chuàng)性和思維的獨(dú)特性,我都是獨(dú)立解題后,先不看答案(除非題目不會(huì)做),直接把解析寫好,再去看答案。
當(dāng)然,如果發(fā)現(xiàn)參考答案有更好的思路,我還是很樂于學(xué)習(xí)和借鑒的。同時(shí),由于本人水平有限,解析中難免出現(xiàn)疏漏甚至錯(cuò)誤之處,敬請(qǐng)諒解。
無論是贊同還是反對(duì)我的看法,都請(qǐng)你給我留言。如果你有新的想法,千萬不要憋在心里,請(qǐng)發(fā)出來大家一起討論。讓我們相互學(xué)習(xí),共同進(jìn)步!
需要本文word文檔、源代碼和課后思考答案的,可以加入 “Python算法之旅”知識(shí)星球 參與討論和下載文件, “Python算法之旅”知識(shí)星球 匯集了數(shù)量眾多的同好,更多有趣的話題在這里討論,更多有用的資料在這里分享。
我們專注Python算法,感興趣就一起來!
相關(guān)優(yōu)秀文章:
