4字母统计包
该包在算法中需要被引用,用来检测暴力破解出的伪明文是否符合英文语法规则,以选取更接近真实的明文。
包的资源路径,该包不需要积分,可自提。
验证伪明文得分的包
该包用于检测伪明文与真实明文的接近程度,利用自然语言的规律进行判别,包中的代码引用了上述4字母统计包中的文件,在运行时注意放在一个文件夹下。该得分越高,则越有可能为自然语言,即越有可能为真明文。不过结果可能存在个别字母的偏差,可自行根据语义修改;密文越大,该方法得到的结果也越精确。
'''
Allows scoring of text using n-gram probabilities
2020/05/06
'''
from math import log10
class ngram_score(object):
def __init__(self,ngramfile,sep=' '):
''' load a file containing ngrams and counts, calculate log probabilities '''
self.ngrams = {}
for line in open(ngramfile):
key,count = line.split(sep)
self.ngrams[key] = int(count)
self.L = len(key)
self.N = sum(self.ngrams.values())
#calculate log probabilities
for key in self.ngrams.keys():
self.ngrams[key] = log10(float(self.ngrams[key])/self.N)
self.floor = log10(0.01/self.N)
def score(self,text):
''' compute the score of text '''
score = 0
ngrams = self.ngrams.__getitem__
for i in range(len(text)-self.L+1):
if text[i:i+self.L] in self.ngrams: score += ngrams(text[i:i+self.L])
else: score += self.floor
return score
代换密码(单表代换)解密
import random
from ngram_score import ngram_score
#参数初始化
#-------------------------仅需修改该处的密文即可-------------------------
ciphertext ='UNGLCKVVPGTLVDKBPNEWNLMGVMTTLTAZXKIMJMBBANTLCMOMVTNAAMILVTMCGTHMKQTLBMVCMXPIAMTLBMVGLTCKAUILEDMGPVLDHGOMIZWNLMGBZLGKSMAZBMKOMKTWNLMGBZKTLCKAMHMIMDMVGBZLXBLCSAZTBMMOMTVPGMOMVKJLTQPXCBPNEJLBBLUILVDKJKZ'
#----------------------------------------------------------------------
parentkey = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
#只是用来声明key是个字典
key = {'A':'A'}
#读取quadgram statistics
fitness = ngram_score('english_quadgrams.txt')
parentscore = -99e9
maxscore = -99e9
j = 0
print('---------------------------start---------------------------')
while 1:
j = j+1
#随机打乱key中的元素
#random.shuffle(parentkey)
#将密钥做成字典
#密文:明文
for i in range(len(parentkey)):
key[parentkey[i]] = chr(ord('A')+i)
#用字典一一映射解密
decipher = ciphertext
for i in range(len(decipher)):
decipher = decipher[:i]+key[decipher[i]]+decipher[i+1:]
parentscore = fitness.score(decipher)#计算适应度
#在当前密钥下随机交换两个密钥的元素从而寻找是否有更优的解
count = 0
while count < 1000:
a = random.randint(0,25)
b = random.randint(0,25)
#随机交换父密钥中的两个元素生成子密钥,并用其进行解密
parentkey[a],parentkey[b]= parentkey[b],parentkey[a]
key[parentkey[a]],key[parentkey[b]] = key[parentkey[b]],key[parentkey[a]]
decipher = ciphertext
for i in range(len(decipher)):
decipher = decipher[:i]+key[decipher[i]]+decipher[i+1:]
score = fitness.score(decipher)
#此子密钥代替其对应的父密钥,提高明文适应度
if score > parentscore:
parentscore = score
count = 0
else:
#还原
parentkey[a],parentkey[b]=parentkey[b],parentkey[a]
key[parentkey[a]],key[parentkey[b]]=key[parentkey[b]],key[parentkey[a]]
count = count+1
#print(count,parentscore)
#输出该key和明文
if parentscore > maxscore:
maxscore = parentscore
print ('Currrent key: '+''.join(parentkey))
print ('Iteration total:', j)
print ('Plaintext: ', decipher,maxscore)
sys.stdout.flush()
破解结果如下,最后停下的值便为最接近明文的结果,可见,该伪明文已可读:
希尔密码解密
import random
from ngram_score import ngram_score
#-------------------------仅需修改该处的密文即可-------------------------
ciphertext = 'RIAIXVVYYOQQBOCFHKBSQGALRWNAXJDSNGNGYLUFUJADTAHANGNGYLDBQGCHOXHAPEITCHGRQQWUSFXVVYAQHOFWMBOBUQILGCMGQTVZRUCRKXITIPLCIQOBDWSIQGHCNAAIWHILVCFSITUEJBQBJBXVEULECHQVYRQIMOELCRYRWHHUMLEDHUCHSFWHXVHKBSAQAPAVHAUEJBWNQBBBAPSUNAQPQGGJ'
#----------------------------------------------------------------------
max_score = -99e9
fitness = ngram_score('english_quadgrams.txt')
# H中参数2为矩阵维数
H = HillCryptosystem(AlphabeticStrings(), 2)
C = H.encoding(ciphertext) #编码,用于提取出密文中的英文而忽略其他字符
print('---------------------------start---------------------------')
for K in H.key_space():
if not K.is_invertible():
continue
M = H.deciphering(K, C)
score = fitness.score(str(M))
if score > max_score:
max_score = score
print("score: ", score)
print(K)
print("PlainText: ", M)
运行结果如下,停止时符合语法:
---------------------------start---------------------------
score: -1761.0604450089113
[1 0]
[0 1]
PlainText: RIAIXVVYYOQQBOCFHKBSQGALRWNAXJDSNGNGYLUFUJADTAHANGNGYLDBQGCHOXHAPEITCHGRQQWUSFXVVYAQHOFWMBOBUQILGCMGQTVZRUCRKXITIPLCIQOBDWSIQGHCNAAIWHILVCFSITUEJBQBJBXVEULECHQVYRQIMOELCRYRWHHUMLEDHUCHSFWHXVHKBSAQAPAVHAUEJBWNQBBBAPSUNAQPQGGJ
score: -1696.4826419233734
[3 0]
[0 1]
PlainText: XIAIZVHYIOOQJOSFLKJSOGALXWNAZJBSNGNGILYFYJADPALANGNGILBBOGSHWXLAFEUTSHCROQQUGFZVHYAQLOTWEBWBYQULCCEGOTHZXUSRMXUTUPVCUQWBBWGIOGLCNAAIQHULHCTSUTYEDBOBDBZVKUVESHOVIROIEOKLSRIRQHLUELKDLUSHGFQHZVLKJSAQAPAVLAYEDBQNOBJBAPGUNAOPOGCJ
score: -1686.4556916705883
[0 3]
[1 2]
PlainText: ARUAJXUVGYMQEBJCQHOBAQVAWRANFXEDCNCNFYXUHUBAWTEHCNCNFYHDAQBCHOEHAPBIBCTGMQSWHSJXUVOAAHEFBMROSUHIOGUMNQDVERNCBKBIRICLAIROODISAQWHANUAFWHIEVUFBIOUDJHQDJJXEEULBCFQHYSQOMBENCHYFWCHNMHECHBCHSFWJXQHOBOAFAHAEHOUDJHWHQRBFAMSANDQAQZG
score: -1666.975608158808
[0 1]
[3 4]
PlainText: UXIAZZWHIIMOEJLSSLIJCOLAIXANNZOBGNGNFINYRYDASPILGNGNFIXBCONSNWILKFRUNSJCMOIQHGZZWHQAWLYTLERWYYJUUCQEPOXHGXXSBMRUNUWVOURWSBKGCOKLANIAVQJUAHUTRUMYPDXOPDZZGKYVNSROLIEOYEXKXSLIVQCLVEPKCLNSHGVQZZSLIJQAPAVAILMYPDBQXORJPAWGANLOCOBC
score: -1645.804727894536
[4 1]
[5 0]
PlainText: IXIEVTYLOEQGOPFMKJSRGOLMWRANJNSHGDGDLWFAJCDIAJARGDGDLWBFGOHAXAAREFTCHARYQGUEFKVTYLQIOLWZBMBCQMLYCKGITOZFUDRSXUTCPACLQUBCWJISGOCFANIEHELYCNSXTCEGBBBSBBVTUQEZHAVCRMICOMLSRSRMHEUBLEDOUBHAFKHEVTKJSRQIPOVEAREGBBNUBSBPPOUYANPMGOJU
score: -1636.6702711616374
[0 3]
[3 6]
PlainText: AXUAJZUHGIMOEJJSQLOJAOVAWXANFZEBCNCNFIXYHYBAWPELCNCNFIHBAOBSHWELAFBUBSTCMOSQHGJZUHOAALETBERWSYHUOCUENODHEXNSBMBURUCVAURWOBIGAOWLANUAFQHUEHUTBUOYDDHODDJZEKUVBSFOHISOOEBKNSHIFQCLNEHKCLBSHGFQJZQLOJOAFAHAELOYDDHQHORJFAMGANDOAOZC
score: -1622.28538113562
[8 3]
[5 0]
PlainText: UNUUHJIHWGOMWRTWMDGBCAVIQJANDFGRCPCPVSTKDUBOAJARCPCPVSJHCALOZUARKNPOLOXGOMYSTUHJIHOOWNQRJOJEOSVUSOCUPARDYRXAZOPOFESPOAJEQBUICASJANUULSVUSRGHPOKOJDJUJDHJYEKHLOHSXUUSWOVOXAXULSYPVABUYPLOTULSHJMDGBOOFSHUARKOJDNUJUJRFSYMANFQCADM
score: -1509.820783666875
[8 3]
[1 4]
PlainText: UNGEPHURKWQSOTBUGLEVCAFMYHANTBYTYDYDLOZCPEZIIHSTYDYDLOVRCAJILESTKNNIJILWQSOOFEPHURMIWNITHIBGEOHEQIOEPALLQTXAXINIXGODOABGOVEMCAAHANGEBOHEKTSRNIIIDLVEDLPHQGWRJIXOJEKOUITIXAJEBOUDVANEUDJIFEBOPHGLEVMIVOTESTIIDLZEVEBTVOASANZYCAFS
score: -1492.9242246562796
[10 7]
[ 1 4]
PlainText: QNKEZHQRIWSSGTTUKLYVMARMOHANXBOTODODBOHCZEHIWHETODODBOJRMAPIBEETINNIPIBWSSGOREZHQRUICNWTDITGYODESIGEZABLSTVAVINIVGGDGATGGVYMMAAHANKETODEITERNIWIFLJEFLZHSGCRPIVOPEIOQIXIVAPETOQDJANEQDPIRETOZHKLYVUIJOXEETWIFLHEJETTJOASANHYMARS
score: -1454.8276553642136
[20 1]
[ 1 4]
PlainText: INSETHIREWWSQTDUSLMVGAPMUHANFBUTUDUDHOXCTEXIYHCTUDUDHOLRGABIHECTENNIBIHWWSQOPETHIRKIONYTVIDGMOVEWIQETAHLWTRARINIRGQDQADGQVMMGAAHANSEDOVEETCRNIYIJLLEJLTHWGORBIROBEEOIIFIRABEDOIDLANEIDBIPEDOTHSLMVKILOFECTYIJLXELEDTLOASANXYGAPS
score: -1440.5385389242883
[ 2 17]
[ 3 8]
PlainText: CNUEBHYRSWUSYTXUALIVIAVMYHANXBMTCDCDROHCREBIMHOTCDCDROPRIAPIBEOTONFIPIJWUSQODEBHYROIKNATHILGCOLEEIAEVAHLGTBATIFIVGODEALGWVEMIAGHANUEDOLEITQRFIYIBLPEBLBHGGGRPINOTEAOUIDIBATEDOMDTAJEMDPIDEDOBHALIVOIFOHEOTYIBLFEPELTFOISANLYIAPS
score: -1405.0489191990162
[20 1]
[ 3 8]
PlainText: INCERHSRUWCSSTBUALGVGATMSHANBBWTIDIDDOPCDERIWHETIDIDDOVRGAVIREETENHIVIXWCSMOZERHSREIONATPIFGIOFEQIAETAPLYTRALIHITGEDQAFGKVQMGAYHANCEZOFEGTMRHISIRLVERLRHYGYRVINOLEAOCIZIRALEZOWDLAXEWDVIZEZORHALGVEIHOPEETSIRLHEVEFTHOGSANFYGAVS
score: -1398.6684497659912
[12 3]
[ 7 20]
PlainText: OXCETTELEEAGAPRMEJOREOTMYRANDNUHIDIDNWTAHCRISJIRIDIDNWTFEOLAZAIRUFTCLATYAGGENKTTELEISLOZHMNCMMRYMKSIROBFEDHSNUTCFAOLCUNCIJESEOCFANCETERYSNAXTCWGLBTSLBTTEQIZLALCVMYCUMFSHSVMTEABDEDOABLANKTETTEJOREIHOPEIRWGLBBUTSNPHOUYANDMEORU
score: -1330.116096349177
[ 4 21]
[11 11]
PlainText: BNCEGHRREWASNTRURLBVEATMLHNNQBHTVDVDNOTCHERIFHVTVDVDNOGREALIZEVTHNTILITWASGONEGHRREIFNBTHINGMOREMISERAOLRTHANITIFGBDCANGVVEMEAPHNNCETOREFTNRTIWIYLTEYLGHEGVRLILOVEYOUIFIHAVETONDDADENDLINETOGHRLBVEIHOPEVTWIYLBETEATHOUSNNDYEARS
score: -1313.3267792056824
[ 4 21]
[23 10]
PlainText: ONCUTJEHEGAMARRWEDOBEATIYJANDFURIPIPNSTKHUROSJIRIPIPNSTHEALOZUIRUNTOLOTGAMGSNUTJEHEOSNORHONEMSRUMOSURABDERHANOTOFEOPCANEIBEIEACJANCUTSRUSRAHTOWOLDTULDTJEEIHLOLSVUYSUOFOHAVUTSAPDADUAPLONUTSTJEDOBEOHSPUIRWOLDBUTUNRHSUMANDQEARM
score: -946.2853518865237
[ 4 21]
[11 24]
PlainText: ONCETHEREWASATRUELOVEATMYHANDBUTIDIDNOTCHERISHITIDIDNOTREALIZEITUNTILITWASGONETHEREISNOTHINGMOREMISERABLETHANITIFGODCANGIVEMEACHANCETORESTARTIWILLTELLTHEGIRLILOVEYOUIFIHAVETOADDADEADLINETOTHELOVEIHOPEITWILLBETENTHOUSANDYEARS
背包加密密码解密
def check(guess): #guess为轮数
#-------------------------仅需修改该处的密文即可-------------------------
pubKey = [615436700291,415460700271,15508700231,846430100773,677471501215,139578302079,179168604148,789306608798,563224517265,364498233536,229056467022,670323428329,115934481316,44989786476,518624653302,149955258190,728568829281,796899516776,546782575075,178164449829,356328899658,712657799316,569303048254,223205396187,446410792374,892821584748,524144817108,132888933895,611875519857,877653387647,839906074973,35774353074]
#----------------------------------------------------------------------
nbit = len(pubKey)
encoded = 6020587936087
print('start %d'%(guess))
# create a large matrix of 0's (dimensions are public key length +2)
A = Matrix(ZZ, nbit + 2, nbit + 2)
# fill in the identity matrix1
for i in range(nbit):
A[i, i] = 1
# replace the bottom 2 rows
for i in range(nbit):
A[i, nbit] = pubKey[i]
for i in range(nbit):
A[i, nbit+1] = 1
# last 2 elements
A[nbit, nbit] = -encoded
A[nbit+1, nbit+1] = -guess
#print(A)
res = A.LLL()
#print(res)
for i in range(0, nbit + 2):
M = res.row(i).list()
flag = True
for m in M:
if m != 0 and m != 1:
flag = False
break
if flag:
print('***************')
print (i, M)
M = ''.join(str(j) for j in M)
# remove the last 2 bits
M = M[:-2]
print('res='+M)
for i in range(1,15):
check(i) #i为轮数
print('end')
解密结果如下: