python實(shí)現(xiàn)柵欄加解密 支持密鑰加密
柵欄加解密是對(duì)較短字符串的一種處理方式,給定行數(shù)Row,根據(jù)字符串長度計(jì)算出列數(shù)Column,構(gòu)成一個(gè)方陣。
加密過程:就是按列依次從上到下對(duì)明文進(jìn)行排列,然后按照密鑰對(duì)各行進(jìn)行打亂,最后以行順序從左至右進(jìn)行合并形成密文。
解密過程:將上述過程進(jìn)行逆推,對(duì)每一行根據(jù)密鑰的順序回復(fù)到原始的方陣的順序,并從密文回復(fù)原始的方陣,最后按列的順序從上到下從左至右解密。
具體實(shí)現(xiàn)如下:所有實(shí)現(xiàn)封裝到一個(gè)類RailFence中,初始化時(shí)可以指定列數(shù)和密鑰,默認(rèn)列數(shù)為2,無密鑰。初始化函數(shù)如下:
def __init__(self, row = 2, mask = None): if row < 2: raise ValueError(u'Not acceptable row number or mask value') self.Row = row if mask != None and not isinstance(mask, (types.StringType, types.UnicodeType)): raise ValueError(u'Not acceptable mask value') self.Mask = mask self.Length = 0 self.Column = 0
加密過程,可以選擇是否去除空白字符。首先是類型檢查,列數(shù)計(jì)算等工作,核心是通過計(jì)算的參數(shù)得到gird這個(gè)二維列表表示的方陣,也是柵欄加密的核心。具體實(shí)現(xiàn)如下:
def encrypt(self, src, nowhitespace = False):
if not isinstance(src, (types.StringType, types.UnicodeType)):
raise TypeError(u'Encryption src text is not string')
if nowhitespace:
self.NoWhiteSpace = ''
for i in src:
if i in string.whitespace: continue
self.NoWhiteSpace += i
else:
self.NoWhiteSpace = src
self.Length = len(self.NoWhiteSpace)
self.Column = int(math.ceil(self.Length / self.Row))
try:
self.__check()
except Exception, msg:
print msg
#get mask order
self.__getOrder()
grid = [[] for i in range(self.Row)]
for c in range(self.Column):
endIndex = (c + 1) * self.Row
if endIndex > self.Length:
endIndex = self.Length
r = self.NoWhiteSpace[c * self.Row : endIndex]
for i,j in enumerate(r):
if self.Mask != None and len(self.Order) > 0:
grid[self.Order[i]].append(j)
else:
grid[i].append(j)
return ''.join([''.join(l) for l in grid])
其中主要的方法是按照列數(shù)遍歷,每次從明文中取列數(shù)個(gè)數(shù)的字符串保存在遍歷 r 中,其中需要處理最后一列的結(jié)束下標(biāo)是否超過字符串長度。然后將這一列字符串依次按照順序加入到方陣grid的各列對(duì)應(yīng)位置。
解密過程復(fù)雜一些,因?yàn)橛忻荑€對(duì)順序的打亂,需要先恢復(fù)打亂的各行的順序,得到之前的方陣之后,再按照列的順序依次連接字符串得到解密后的字符串。具體實(shí)現(xiàn)如下:
def decrypt(self, dst):
if not isinstance(dst, (types.StringType, types.UnicodeType)):
raise TypeError(u'Decryption dst text is not string')
self.Length = len(dst)
self.Column = int(math.ceil(self.Length / self.Row))
try:
self.__check()
except Exception, msg:
print msg
#get mask order
self.__getOrder()
grid = [[] for i in range(self.Row)]
space = self.Row * self.Column - self.Length
ns = self.Row - space
prevE = 0
for i in range(self.Row):
if self.Mask != None:
s = prevE
O = 0
for x,y in enumerate(self.Order):
if i == y:
O = x
break
if O < ns: e = s + self.Column
else: e = s + (self.Column - 1)
r = dst[s : e]
prevE = e
grid[O] = list(r)
else:
startIndex = 0
endIndex = 0
if i < self.Row - space:
startIndex = i * self.Column
endIndex = startIndex + self.Column
else:
startIndex = ns * self.Column + (i - ns) * (self.Column - 1)
endIndex = startIndex + (self.Column - 1)
r = dst[startIndex:endIndex]
grid[i] = list(r)
res = ''
for c in range(self.Column):
for i in range(self.Row):
line = grid[i]
if len(line) == c:
res += ' '
else:
res += line[c]
return res
實(shí)際運(yùn)行
測(cè)試代碼如下,以4行加密,密鑰為bcaf:
rf = RailFence(4, 'bcaf')
e = rf.encrypt('the anwser is wctf{C01umnar},if u is a big new,u can help us think more question,tks.')
print "Encrypt: ",e
print "Decrypt: ", rf.decrypt(e)
結(jié)果如下圖:

說明:這里給出的解密過程是已知加密的列數(shù),如果未知,只需要遍歷列數(shù),重復(fù)調(diào)用解密函數(shù)即可。
完整代碼詳見這里
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python 實(shí)現(xiàn)RSA加解密文本文件
- python實(shí)現(xiàn)凱撒密碼、凱撒加解密算法
- Python實(shí)現(xiàn)密鑰密碼(加解密)實(shí)例詳解
- 利用python實(shí)現(xiàn)凱撒密碼加解密功能
- Python3加密解密庫Crypto的RSA加解密和簽名/驗(yàn)簽實(shí)現(xiàn)方法實(shí)例
- Python內(nèi)置方法實(shí)現(xiàn)字符串的秘鑰加解密(推薦)
- python實(shí)現(xiàn)AES和RSA加解密的方法
- python下讀取公私鑰做加解密實(shí)例詳解
- python des,aes,rsa加解密的實(shí)現(xiàn)
相關(guān)文章
Python3實(shí)現(xiàn)發(fā)送QQ郵件功能(附件)
這篇文章主要為大家詳細(xì)介紹了Python3實(shí)現(xiàn)發(fā)送QQ郵件功能,附件方面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Python實(shí)現(xiàn)簡單的文本相似度分析操作詳解
這篇文章主要介紹了Python實(shí)現(xiàn)簡單的文本相似度分析操作,結(jié)合實(shí)例形式分析了Python基于分詞API庫jieba及文本相似度庫gensim針對(duì)文本進(jìn)行相似度分析操作的實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下2018-06-06
使用Python和FastAPI實(shí)現(xiàn)MinIO斷點(diǎn)續(xù)傳功能
在分布式存儲(chǔ)和大數(shù)據(jù)應(yīng)用中,斷點(diǎn)續(xù)傳是一個(gè)重要的功能,它允許大文件上傳在中斷后可以從中斷點(diǎn)恢復(fù),而不是重新上傳整個(gè)文件,本文將介紹如何使用Python封裝MinIO的斷點(diǎn)續(xù)傳方法,需要的朋友可以參考下2024-12-12
使用PyQt5實(shí)現(xiàn)圖片查看器的示例代碼
這篇文章主要介紹了使用PyQt5實(shí)現(xiàn)圖片查看器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
matplotlib 范圍選區(qū)(SpanSelector)的使用
這篇文章主要介紹了matplotlib 范圍選區(qū)(SpanSelector)的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Django?事務(wù)回滾的具體實(shí)現(xiàn)
本文主要介紹了Django?事務(wù)回滾的具體實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02

