Python位操作和數(shù)據(jù)校驗(yàn)與加密

二進(jìn)制

按位計(jì)算都是在二進(jìn)制上進(jìn)行的。
十進(jìn)制的位是個(gè)十栅表、百笋鄙、千、萬怪瓶、十萬萧落、百萬...987這個(gè)數(shù)字9在百位,8在十位洗贰,7在個(gè)位找岖,其實(shí)就是987=9x100+8x80+7x1。所以位就是數(shù)字的順序位置敛滋。
二進(jìn)制的位是1许布,2,4绎晃,8蜜唾,16,32...比如1011就是1x8+0x4+1x2+1x1=11箕昭。
Python里面用bin(n)可以把整數(shù)n變?yōu)?b開頭的二進(jìn)制字符串灵妨,比如

>>> bin(11)
'0b1011'
>>> bin(9)
'0b1001'

異或運(yùn)算

Python中異或運(yùn)算的符號(hào)是6數(shù)字上面的^。
對(duì)于兩個(gè)二進(jìn)制落竹,比如1011和1001泌霍,把它們異或之后得到的是0010,因?yàn)閮蓚€(gè)二進(jìn)制同位上相同述召,那么結(jié)果二進(jìn)制這個(gè)位上就是0朱转,不同就是1,參考下面的代碼:

>>> 11^15
4
>>> print(bin(11));print(bin(15));print('0b0100')
0b1011
0b1111
0b0100

bin(4)其實(shí)是0b100积暖,等同于0b0100藤为。因?yàn)槲覀兌贾朗M(jìn)制0030就是30,前面的0只是占位置的夺刑。

注意1011^1111=0100這個(gè)事實(shí)缅疟,只看前兩位,簡(jiǎn)化一下的例子有10^11=01遍愿,只看后兩位11^11=00存淫。
更簡(jiǎn)單的例子是1^1=0,1^0=1沼填,0^1=1桅咆,0^0=0,其實(shí)就是每一位上相同得0坞笙,相異得1岩饼。

再看代碼中最后三行的數(shù)字荚虚,你會(huì)發(fā)現(xiàn)任意兩個(gè)異或的結(jié)果都是第三個(gè),11^15=4籍茧,11^4=15版述,15^4=11。兩個(gè)數(shù)字a硕糊,b異或后得到第三個(gè)數(shù)字c院水,那么這三個(gè)數(shù)字互為其余兩個(gè)數(shù)字的異或結(jié)果

另外简十,任何數(shù)字和自己異或結(jié)果都是0檬某,因?yàn)槊恳晃欢枷嗤恳晃唤Y(jié)果就都是0螟蝙。

數(shù)據(jù)校驗(yàn)

假如你有一段文字恢恼,發(fā)送給我,我收到后如何確保中間傳輸?shù)臅r(shí)候沒有出錯(cuò)或者丟失或者被其他人中間做了修改胰默?

如果讓你再重新發(fā)送一遍场斑,我把兩遍收到的對(duì)比,可不可以牵署?不行漏隐!首先同樣的錯(cuò)誤很可能會(huì)再次發(fā)生,兩遍都錯(cuò)的可能性并不信浮青责;其次即使發(fā)現(xiàn)兩次收到的不同,但哪一次才是正確的呢取具?

換個(gè)思路脖隶,我們事先都約定好一個(gè)數(shù)字C比如100,你把要發(fā)送的數(shù)據(jù)A先和C做異或得到B暇检,把A和B都發(fā)給我产阱,我收到之后,再把收到的數(shù)據(jù)A0和B0做異或块仆,得到結(jié)果C0构蹬,C0再和C做異或,最終應(yīng)該是0悔据,這樣就可以確定數(shù)據(jù)是正確的了庄敛,如果不是0就表示數(shù)據(jù)出了問題。

為什么蜜暑?因?yàn)锽=A^C铐姚,我用B0^A0=C0策肝,再用C0^C=0自身異或?yàn)?完成驗(yàn)證肛捍。

當(dāng)然如果數(shù)據(jù)A很多隐绵,那么你可以用C和A中的每個(gè)數(shù)字做異或,得到最后一個(gè)簡(jiǎn)單的數(shù)字B拙毫,把這個(gè)數(shù)字B放在A的最前面和A一起打包成D發(fā)過來依许,我只要把D的第一個(gè)數(shù)字當(dāng)做B,其余當(dāng)做A就可以了缀蹄。

參照下面的代碼:

data = '你好峭跳,Python!' #要發(fā)送的數(shù)據(jù)
A = [ord(t) for t in data] #數(shù)據(jù)變成待傳送的列表[20320, 22909, 65292,...]
C = 100  #用C初始缺前,下面循環(huán)和A每一項(xiàng)做異或
for t in A:
    C = C ^ t
B = C #B是C和A每一項(xiàng)異或的結(jié)果蛀醉,這時(shí)C已經(jīng)變成B,不再是100
D = [B] + A #拼合傳送數(shù)據(jù)
A0 = D[1:] #A0是D減去第一項(xiàng)剩余的其余部分
B0 = D[0]  #用B0是D的第一項(xiàng)衅码,下面循環(huán)和A0每一項(xiàng)做異或
for t in A0:
    B0 = B0 ^ t
C0 = B0 #C0是B0和A0每一項(xiàng)異或的結(jié)果
C0 ^ 100 #因?yàn)镃已經(jīng)不再是100拯刁,所以這里不能使用C

ord('a')獲得字母a對(duì)應(yīng)的計(jì)算機(jī)ascii編碼數(shù)字,所有的字符包括中文日文逝段,每一個(gè)都對(duì)應(yīng)一個(gè)ascii編碼數(shù)字垛玻。[int(t) for t in '123']語(yǔ)法得到的是[1,2,3]

如果你修改D=[B]+A+[33,1223,55]那么最后結(jié)果就不再是0,表示數(shù)據(jù)傳輸時(shí)候出了錯(cuò)誤奶躯。

我們都知道電腦會(huì)不斷地發(fā)送信息給遠(yuǎn)程服務(wù)器帚桩,遠(yuǎn)程服務(wù)器也不斷的發(fā)送信息給電腦,自動(dòng)取款機(jī)也是一臺(tái)電腦嘹黔,如果你把它的網(wǎng)線拔下來插在你的筆記本上账嚎,然后編寫一個(gè)程序來假冒取款機(jī)發(fā)送信息給銀行遠(yuǎn)程服務(wù)器,那么你就可以直接修改你的存款余額参淹。

而有了校驗(yàn)機(jī)制醉锄,你編寫的程序因?yàn)椴恢廊】顧C(jī)使用的秘鑰(就是上面說的C=100),那么你發(fā)送的數(shù)據(jù)就會(huì)被銀行服務(wù)器認(rèn)為是錯(cuò)誤信息浙值。

實(shí)際情況要比這復(fù)雜很多恳不。

信息加密

仍然利用異或算法,我們可以把數(shù)據(jù)A和秘鑰C異或生成X开呐,A^C=X烟勋,如果你不知道C,即使截獲到X也沒有辦法讀取出A來筐付,所以異或本身就是一種加密方法卵惦。

如果你獲得了X,也知道C瓦戚,那么當(dāng)然可以用C^X=A得到A沮尿。這就是解密。

和上面的B不同,B只是一個(gè)數(shù)字畜疾,而X則是對(duì)A的每一個(gè)數(shù)字加密后得到的新數(shù)字列表赴邻。

可以從下面的代碼中理解:

def enctrypt(text, key):
    text_asc_arr = [ord(t) for t in text]  #將’你好 Python!‘轉(zhuǎn)為ascii碼列表[20320, 22909, 32,...]
    key_asc_arr = [ord(t) for t in key]  #將key轉(zhuǎn)為ascii碼列表[24,32,1543]
    key_len = len(key_asc_arr)#秘鑰單詞長(zhǎng)度
    for n in range(len(text_asc_arr)):
        k = n % key_len #秘鑰單詞循環(huán)往復(fù)使用
        text_asc_arr[n] = text_asc_arr[n] ^ key_asc_arr[k] #異或操作成為[451,223,116,...]
    return ' '.join([bin(t)[2:] for t in text_asc_arr]) #返回字符串拼接格式‘1010101 101011 1100 01...'


def decrypt(text, key):
    asc_str_arr = text.split(' ') #將字符串拆成列表‘1010101 1010...'-->['101010','1010',...]
    text_asc_arr = [int(s, 2) for s in asc_str_arr] #轉(zhuǎn)成ascii列表[451,223,116,...]
    key_asc_arr = [ord(t) for t in key]#轉(zhuǎn)為ascii碼列表[24,32,1543]
    key_len = len(key_asc_arr)#秘鑰單詞長(zhǎng)度
    for n in range(len(text_asc_arr)):
        k = n % key_len#秘鑰單詞循環(huán)往復(fù)使用
        text_asc_arr[n] = text_asc_arr[n] ^ key_asc_arr[k]#異或操作成為[20320, 22909, 32,...]
    return ''.join([chr(int(t)) for t in text_asc_arr])#返回字符串拼接格式‘你好 Python啡捶!'


en = enctrypt('你好 Python姥敛!', '我很好')
de = decrypt(e, 'wobuhao')
de2 = decrypt(e, '我很好')
print(en)
print(de)
print(de2)

輸出的結(jié)果是

10110101110001 11011110101 101100101011101 110001001000001 101111111110001 101100100001001 110001001111001 101111111100111 101100100010011 1001110100010000
??夿戴徙奨或徐奼鵲
你好 Python!

其中de = decrypt(e, 'wobuhao')使用了錯(cuò)誤的秘鑰'wobuhao'導(dǎo)致了解密出來都是亂碼瞎暑。

異或加密只是眾多加密方式中的一種彤敛。之所以常用異或進(jìn)行校驗(yàn)或簡(jiǎn)單加密,是因?yàn)楫惢蚴腔诙M(jìn)制計(jì)算的了赌,速度非常的快墨榄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市勿她,隨后出現(xiàn)的幾起案子渠概,更是在濱河造成了極大的恐慌,老刑警劉巖嫂拴,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件播揪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡筒狠,警方通過查閱死者的電腦和手機(jī)猪狈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辩恼,“玉大人雇庙,你說我怎么就攤上這事≡钜粒” “怎么了疆前?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)聘萨。 經(jīng)常有香客問我竹椒,道長(zhǎng),這世上最難降的妖魔是什么米辐? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任胸完,我火速辦了婚禮,結(jié)果婚禮上翘贮,老公的妹妹穿的比我還像新娘赊窥。我一直安慰自己,他們只是感情好狸页,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布锨能。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪址遇。 梳的紋絲不亂的頭發(fā)上叔收,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音傲隶,去河邊找鬼。 笑死窃页,一個(gè)胖子當(dāng)著我的面吹牛跺株,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脖卖,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼乒省,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了畦木?” 一聲冷哼從身側(cè)響起袖扛,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎十籍,沒想到半個(gè)月后蛆封,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勾栗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年惨篱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片围俘。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砸讳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出界牡,到底是詐尸還是另有隱情簿寂,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布宿亡,位于F島的核電站常遂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挽荠。R本人自食惡果不足惜烈钞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坤按。 院中可真熱鬧毯欣,春花似錦、人聲如沸臭脓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至砚作,卻和暖如春窘奏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葫录。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工着裹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人米同。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓骇扇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親面粮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子少孝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容