当曲高和寡不是一个结果的时候,它往往会成为一种错觉,……,若你的思考真的精妙到了只有你自己能理解,那你岂不是更应该将你精妙的思考分享给他人?

Vigenere密码无密钥求解

0.前言

最近摸了很长时间的鱼,然后最近突然想搞一个Vigenere密码的自动求解,花了不到一天来实现了一下这个东西,不过受限于自己的水平,没有搞的太难。当然,代码部分不是全部都是从 0 开始的,关于Vigenere密码的加解密实现主体是 pycipher 这个扩展库中的 vigenere 部分,这个库中关于 base 的实现会把所有的字母换为大写并且去掉里面的出去字母外的所有东西,这样无论是加密还是解密看起来都会很费劲,简单改了改,改成了分开大小写和保留非字母字符的样子。
至于破解部分的代码来源于 维吉尼亚密码(Vigenere)(二),当时找的时候找到了这个代码,不过找到代码是挺早以前的事情了,以至于手中只有代码而找不到出处了。不过今天写博客的时候又去翻了翻,终于是找到了。这篇博客中的代码分为两部分,猜测密钥长度和猜测密钥(解密部分不算在内的话),而且这其中还需要进行人工检查。所以进行了一下修改,将可能性最大的一种方案提出来作为最有可能的 key 来进行解密。只不过这样做也不是没有缺陷,就是有可能可能性最高的方案不是正确的密钥 key ,这个问题最好还是有语义检查来解决,可惜不太会……
不过相对应的,在类的实现中留下了可以进行自己选择密钥长度和密钥的功能
代码如下:

1.classicalcipher.py

from string import ascii_lowercase, ascii_uppercase
upperTuple = tuple(ascii_uppercase)
upperDict = dict(map(reversed, dict(enumerate(ascii_uppercase)).items()))
lowerTuple = tuple(ascii_lowercase)
lowerDict = dict(map(reversed, dict(enumerate(ascii_lowercase)).items()))

class Cipher(object):
    def encipher(self,string):
        return string
        
    def decipher(self,string):
        return string
        
    def a2iUpper(self,ch):
        ch = ch.upper()
        return upperDict[ch]
    
    def a2iLower(self, ch):
        ch = ch.lower()
        return lowerDict[ch]

    def i2aUpper(self,i):
        i = i%26
        return upperTuple[i]
    
    def i2aLower(self, i):
        i = i % 26
        return lowerTuple[i]

2.Vigenere.py

from secrets import choice
from classicalcipher import Cipher

F = [
0.0651738, 0.0124248, 0.0217339,
0.0349835, 0.1041442, 0.0197881,
0.0158610, 0.0492888, 0.0558094,
0.0009033, 0.0050529, 0.0331490,
0.0202124, 0.0564513, 0.0596302,
0.0137645, 0.0008606, 0.0497563,
0.0515760, 0.0729357, 0.0225134,
0.0082903, 0.0171272, 0.0013692,
0.0145984, 0.0007836
]   

class Vigenere(Cipher):
    def __init__(self, key = 'fortification'):
        self.key = [i for i in key]
    
    def encipher(self, string):
        ret = ''
        ind = -1
        for i in iter(string):
            if i.isalpha() :
                ind = (ind + 1) % len(self.key)
                if i.isupper() :
                    ret += self.i2aUpper(self.a2iUpper(i) + self.a2iUpper(self.key[ind]))
                else :
                    ret += self.i2aLower(self.a2iUpper(i) + self.a2iLower(self.key[ind]))
            else :
                ret += i
        return ret

    def decipher(self, string):
        ret = ''
        ind = -1
        for i in iter(string):
            if i.isalpha() :
                ind = (ind + 1) % len(self.key)
                if i.isupper() :
                    ret += self.i2aUpper(self.a2iUpper(i) - self.a2iUpper(self.key[ind]))
                else :
                    ret += self.i2aLower(self.a2iUpper(i) - self.a2iLower(self.key[ind]))
            else :
                ret += i
        return ret

class NoKeyVigenere(Vigenere):
    def __init__(self, cipher):
        self.cipher = cipher
        self.cipher_alpha = remove_punctuation(cipher)
        self.key_box = {}      # 密钥长度对应密钥的组成列表,以字典形式存储,其中值的类型为列表的列表,[[('k', 0.009825224799999997), ('v', 0.024006790400000012), ('l', 0.0283841072), ……], [('v', 0.024006790400000012), ('l', 0.0283841072), ……]]
        self.key_len_box = None  # 密钥可能的长度,越靠前概率越高, 大概是 (11, 0.001573206494528287) 这种类型的, 50位
        self.most_likely_key_len = None
        self.key = None
    
    def find_most_likely_key_len(self):
        '''
        默认 key 的范围是在 1 ~ 50 之间
        '''
        self.key_len_box = [(0, 0.0) for _ in range(50)]
        for i in range(0, 50):
            self.key_len_box[i] = (i + 1, abs(0.065 - count_key_len_CI(self.cipher_alpha, i + 1)))
        self.key_len_box = sorted(self.key_len_box, key = lambda x: x[1])
        self.most_likely_key_len = self.key_len_box[0][0]
    
    def get_most_likely_key(self):

        #将密钥长度和对应的密钥的组成列表作为键值对存储
        self.key_box[self.most_likely_key_len] = one_key(self.cipher_alpha, self.most_likely_key_len)
        
        tmp = self.key_box[self.most_likely_key_len]
        most_likely_key = [i[0][0] for i in tmp] # 遍历一个元素为列表的列表,其中去元素中的第一个元组,中的第一个元素:字母
        self.key = ''.join(most_likely_key)

    def add_key_composition(self, key_len): # 添加一个 key_len 长度的密钥组成进 self.key_box
        self.key_box[key_len] = one_key(self.cipher_alpha, key_len)
    
    def get_key_from_positon(self, key_len, pos = 0):
        tmp = self.key_box[key_len]
        choice_key = [i[pos][pos] for i in tmp]
        
        return ''.join(choice_key)
        a = 1

    def decipher(self):
        ret = ''
        ind = -1
        for i in iter(self.cipher):
            if i.isalpha() :
                ind = (ind + 1) % len(self.key)
                if i.isupper() :
                    ret += self.i2aUpper(self.a2iUpper(i) - self.a2iUpper(self.key[ind]))
                else :
                    ret += self.i2aLower(self.a2iUpper(i) - self.a2iLower(self.key[ind]))
            else :
                ret += i
        return ret

    def decipher_by_specify_key(self, key):
        ret = ''
        ind = -1
        for i in iter(self.cipher):
            if i.isalpha() :
                ind = (ind + 1) % len(key)
                if i.isupper() :
                    ret += self.i2aUpper(self.a2iUpper(i) - self.a2iUpper(key[ind]))
                else :
                    ret += self.i2aLower(self.a2iUpper(i) - self.a2iLower(key[ind]))
            else :
                ret += i
        return ret

def remove_punctuation(cipher):
    '''
    将密文中的非字母去除
    '''
    cipher_alpha = ''
    for i in range(len(cipher)):
        if (cipher[i].isalpha()):
            cipher_alpha += cipher[i]
    return cipher_alpha

def count_CI(cipher):
    N = [0.0 for i in range(26)]
    L = len(cipher)
    if cipher == '':
        return 0
    else:
        for i in range(L):     #计算所有字母的频数,存在数组N当中
            if (cipher[i].islower()):
                 N[ord(cipher[i]) - ord('a')] += 1
            else:
                 N[ord(cipher[i]) - ord('A')] += 1
    CI_1 = 0
    for i in range(26):
        CI_1 += ((N[i] / L) * ((N[i]-1) / (L-1)))
    return CI_1

def count_key_len_CI(cipher_alpha, key_len):
    cipher_block = ['' for _ in range(key_len)]
    aver_CI = 0.0
    count = 0
    for i in range(len(cipher_alpha)):
        ind = i % key_len
        cipher_block[ind] += cipher_alpha[i]
    
    for i in range(key_len):
        cipher_block[i] = count_CI(cipher_block[i])
        aver_CI += cipher_block[i]
    aver_CI = aver_CI / len(cipher_block)
    return aver_CI

def count_CI2(cipher,n):     # n 代表我们猜测的秘钥,也即偏移量
    N = [0.0 for i in range(26)]
    L = len(cipher)
    for i in range(L):     #计算所有字母的频数,存在数组N当中
        if (cipher[i].islower()):
            N[(ord(cipher[i]) - ord('a') - n)%26] += 1
        else:
            N[(ord(cipher[i]) - ord('A') - n)%26] += 1  
    CI_2 = 0
    for i in range(26):
        CI_2 += ((N[i] / L) * F[i])
    return CI_2

def pre_5_key(cipher):
    M = [(0,0.0) for i in range(26)]
    for i in range(26):
        M[i] = (chr(ord('a')+i),abs(0.065 - count_CI2(cipher,i)))
    M = sorted(M,key = lambda x:x[1])   #按照数组第二个元素排序

    return M   # M 是一个 list ,元素为 ('k', 0.009825224799999997) 这样的形式

def one_key(cipher_alpha,key_len):
    un_cip = ['' for i in range(key_len)]   
    for i in range(len(cipher_alpha)):     # 完成分组工作
        z = i % key_len
        un_cip[z] += cipher_alpha[i]
    key_box = [[] for _ in range(key_len)]
    for i in range(key_len):
        key_box[i] = pre_5_key(un_cip[i])
    return key_box

if __name__ == '__main__':
    '''
    在使用的时候,如果文本量较大,有跨行的情况,可以使用 3引号 字符串
    '''
    cipher1 = 'Dlcns rul mvmorro we opfl wril ucl ppsz syqckbv vv mbcr xfwh prb jbsd ayjh kr wijk dlci tirt yvub hpaodv hnk hek rdsd ivr yekp! Bnsrp dhht iss soew ao kroek;cc nklrl yyy uwbk wv gv;bo afwh prb whnd xm xs,shjabso cmq vryl ouli sla zzil aud yrc yvrqje ao ns yhz kkl toixkq ucl zhna ty hm.Iop bvu oafi cjcljo hhpzmlagj wv mhko cmq gnhlt,lnyyed hilhlz ty qygs prb saryre,abfxnh zobvms hf nlew yyy fqarq,lnvuql fkdv wv mhko cmq vrswy? Hlgewo dlw fobrcijb we rahlrc’wfksj.Lm yvu pich hyda ia hevro mfx,pt wryfyxzp kbras dlc khyhy plrcsl, pcf.Woe oaztgagk rm plozpc zce’w uejecwynwcb oace dlc xsjw vf lvovwpvzqn;toei nsoh ddre aho qmoh fi lvlrixfebx woaa cyqco ocrug ahomp sop.Khpwixiqo zzhz fvr dlmos nkv cyy,dlmos nkv hbrd, xfkgv zoo oafi qaoifoek,axh rdcjh dhv hkzc pfzhk,fvr yrju hyhf chn ktnnstlhtl tri gidfuaauco sd lsfssedhy lyrs krbcoen xfawi opvls.Vsta pvjpnz wsxf w gdlse,nryaq swkk h kpsc elz segz wptr e raoi.Woe irskfpsjw muaubi uezc dswhyc fc xojhk ou a pspcckwln wacx, wki tdu’t no yr uazc lu lpfoylpwc bvu sed km kt prbr wacx dwwcxyez axh faoiwhcoec.Afab prb wlro fmnb,prb wlro gpuwej hnk efipuceh hrvuxh wki ndz stivmlc.Zzyl yvub pgbs jr ahht glcj mfx kil,yyy pa hyh vnl wrs go gdlsiug krb ajvufoue kvmqbu bvu ps mvwebx.Ssehso wcjr kkps tecwycs kr ahvso tckdch dhv moel ocdhahpnq xm ucl,wv tooci udc ydce aoegfar prbr sipi gj ceh daf ob elkhyhy,tv trsqa kyr tare iss oazol woex cmq fvdslf noib eh,kr ahvso xfwh ddre foe wca hyh irpgrxcn gzgl om trmlcg nkln foe epa fvdslf dyal,pc kkvsl wrs wki ndut ao vir pvvp rnvw dlyp mfx hpwroggwhv woepr pvgabuvoiw.Axh gb mfx kou’t, nsl’p kfuyy,uodlgju sdk wplv lyldvq ao foe,cmq kzos jbsd qgog fxa ou tri mldfuauuidc rk pilnhaex wmisfql’s kai agpv kkps tecwycs.'
    cipher2 = '''g vjganxsymda ux ylt vtvjttajwsgt bl udfteyhfgt
oe btlc ckjwc qnxdta 
vbbwwrbrtlx su gnw nrshylwmpy cgwps, lum bipee ynecgy gk jaryz frs fzwjp, x puej jgbs udfteyhfgt, gnw sil uuej su zofi. sc okzfpu bl lmi uhzmwi, x nyc dsj bl lmi enyl ys argnj yh nrgsi. nba swi cbz ojprbsw fqdam mx. cdh nsai cb ygaigroysxn jnwwi lr msylte.
cw mekr tg jptpzwi kdikjsqtaz, ftv pek oj pxxkdd xd ugnj scr, yg n esqxwxw nba onxw au ywipgkj fyiuujnxn gnss xwnz onxw jnahl avhwwxn vzkjpu nrofch fvwfoh. v jwhppek lmi vyutfp hbiafp hcguj at nxw gyxyjask ib hw seihxsqpn vtvjttajwsx ds zzj xnegfsmtf egz wtrq lt mbcukj sc hy. qty wnbw ss bbxsq vxtnl ys ghrw zw cbx vt cdh vgxwtfy ssc brzzthh bl wsjdeiwricg cw mekr zjzi grgktr ib lwfv.
vbbwwrbrtlx hteonj xwroj oyhg vgbigf ljtq iuk utrhrtl tj iuk ytztetwi. cdh nsai crolmig fudngxgkv ssg ekujmkrj gzvh. jk vnh cbz aszxgk qty. nba vt rdg qfta jf, tgw hd lum prdj umw aderv. hcqrxkuerr jgjw cbz dni lvzznr nbaj gsgqkjx. hd aul ylxaq lmei lum hec oaaqh xg, gk yldhmz nx lrxw f tjorah gdaylwyrgogs tgbpwhx. nba ufrcbz. ay mh nt shx ds tsyygr gfi mi txgbw xgywqj iuxgzkw baj hsaykuymkr guymday.
qty wnbw ssi rtyfktq of tyg txwfx paj yfxwrxask rbtnjvhnzatr, cbx vnh nba uwipgk lmi lrgdyl ds umw qpeqwytaniwx. cdh jg ssi xtgb sje imqxjek, gzv tgnahw, de zzj ycjxayxta igiih gnsy eaeksic eeunnht baj xsrvkld qdek gwhte zzfr rbadi ft bhlfmcrj td ecl ux dsje oeushvzatrh.
lum hppvs lmigr gjj tgbhdjqh nsgsk jf zzfx nba fjis gu ktpkr. egz yhr zznw rygar eh nt wcgjfk lt mcigvj sje vjjgxailx. qpae gk xwryw uvdorwrw sbt'l jbxfz. omigr zzjvt nxw wipy igsjavilx, awrxw yltek swi leuflw, lr caqp xqkfymul zzjq paj sihgryk yltz hq tyg zkssw. lr gjj jdesask dhx gbr hbiafp rbtlwerg. zznw vbbwwrpaiw bmay gjnwt niutvsvty ys iuk utrsvzatrh bl gzv lbxdi, rdg egzvh. baj bsgyj ax hxslwwicg.
iqgigfvshi rbtknwif ux yvpayshxxbtk, wianzatrhuohx, ecq zztyvuz aywtyl, swvplkv qmzr g kyecqofl apik as xwr cwg su baj hsbzafngpgogsw. dhxk nw p jujqh iugl nw qbzz jzteeomigr gfi rdjnwwi, qhz ay mh aul bltek tthxry dnzt.
jk swi reksymct g otvaq zzfx pyr efc tazww axgngzx eeonnpttk gw tgrpmimrr guhsgqkv gc gniw, jgdaueng ebcww, qxyolfvn sujhi, de ylfxxbt gk fxezz.
bi pek uwipgofl e lbxdi awrxw frnbtw, frnjnwwi bne wctgryk mmh bx zjv qrrajjh, au efxirx zta hvtyzppe, cayldhz xjeg bl tjmct igjvrrj asxd fodjrrr uj hscsujrmil.
egzv armsq gdaiwuxh bl hwserxld, imcxwxwxbt, aiicgold, qdikejri, ntv hscgkpy hd aul fteye lt yh. gnwd egr gdq fpfkv tr bnzljv, paj lmigr ok ss bnzljv wrxw.
tyg vjwsxxgowx lpik ft fdqowx, wd, htdnot lum, bi rntftx dozsnr dejww fn cnqxmrnr utigpogs. at okdnikr zzfx ueue jxwvik, jravmzyicrj kjpu-vtljvtfz, ssh iuk utqbbtojea, baj lskrxffrrr caqp tzkjli. dhx aiicgolnih zgq gi svylwmqhzwi ereukx qpae gk cdhx bzvxfjahxxbtk. ylt btdd ppj zzfx pyr gzv rbtkymihkfy gjyzmwih jumqh vrtwweaye jjgdttaei xf zzj kdyjws vjyk. oj ldck oj axyr tj eqyk lt fjvrv tyg cgjymrhrsw wdyalnscf uf ylpg hsxmh. oal bi rntftx ppiwux iuk ktpjgogsw nba swi pgzwrtivty ys xzvgxi.
xa zzj ycvzwi winzwx, cdh nsai ibjsd ggrgljh p ygo, ylt gkdjgdzsmsmrnzatrh ekxtvb nil, blxpn jjtjqosyih lumw sla igswivzmymda gfi mcfadyw iuk vwipzy gk ntslwwwda, csxlxamltr, bvrd, resvygs, htguizikvrdj, ecq hjfrsrok. yltfk vwipzy ezwi auo gi qbxf frtj of zw.
nba swi irxjnjxrj gk cdhx gbr ruodivta, yasgt gnwd egr tsymkry as e lbxdi awrxw dsj jodq eajgqx ft vsenkgntlx. ftpgmxi nba xjeg gnwr, cdh kfyvjfz qtyg oajjejpxshmtf cayl iuk hfvtazsq vtfvgswxoodnxxry qty pek lts rbcswhal zg hscsxgsx nbajxiaikk. nr dhx otvaq, gdq xwr ywsxxzkfyw paj wctgryknscf ux mybntayc, ueue ylt qktfwxam lt xwr gfliavi, swi enxlx su n ywfqaryk bldyk, lmi vyutfp rbtnjvhnzatr ds hayw. lr issrdg ywuegnzw ylt noj ylpg iztotf ljtq iuk snv jcuf blxpn onrvf hwfx.
xa iznrp, tkjrecl, ljfrrr, xmxwxn, yaskpcujj, minrq frs gnw zrxgkv xxpgkk, dsj nxw yvnvty ys lnxv tju gnw amghy gk pxokjyc ql kjjgivty lypej htwif gl ylt sxgsxxrxk tj rlhwwweniw. yltfk efc zrkh tyi gnw hscggynsc suj f wbnrd ymbr, hmy xwre onpa aul bsgx of f aderv ylpg caqp hbuf gi qygfpiirj as fxg-hwfvxam ejhxn.
egzv xaijjehvtyqc doygqiir ofksgzglnsc vtvzwieowx adhrv uigcklzeir zzjqhrrnjw ql vjttdfofl ppjy, as ebrxahe paj wqwtjnwwi, iugl hppvs lt sla yhjiru olxias zzwsjtngzx iuk otvaq. zzjwt ygox adhrv iirygjj msrgk ys qr gftxwrx ashjfzjnea cxgiyrg, tg rsgr tggpt gnss txt ojtr. xa umw aderv, blpgknjv iuk zzqpa sash bne uwipgk ufr qr xwuvdqaujh paj vnwieotzxtq ofkmcvzwqc pg tg hshg. zzj kabhsq gdabwdecpk gk xwbaymx cb rgskte xwvyxekk dsje lshxdeowx xd niutqeyokm.
xwryw nrreksxmctrq mshgodj ecq igqscvgd ripfajjw eyguj yh vt lmi hnsw ushvzatr pf zztwt cxwamdhy dtztey gk jgrkvtq paj kjpu-qkljvbvtsymda czt lpq zg wiyril ylt nalmsgvzajw ds jaxxpaz, msmcsujris cuojvh. jk ezwi qkuqegr umw zxezmfp hrrnjw xzsmsi ib egzv hbbwwixttld, ikrt sx at pufymchk lt gdaywsx ib egzv ghrw tzte umw fdqowx. at jodq weeksi sjeywqztf guwshf zzj tantwy wd gnsy rd btw hec nxjjwi baj yldhmzyw.
lr caqp reksyi p ponnpxmglnsc bl lmi bvtv nr rlhwwweniw. ren vz tj qdek zzqpak ssh unoj ylpa zzj aderv dsje mgaigaswsxh ugnj qpqk tjjdek.
xqev vy ewgis balicrxw hvnczg hvppq efr, eyksxi pqj mshteyutvt ntv hygye twerry.'''
    a = NoKeyVigenere(cipher2)
    a.find_most_likely_key_len()
    a.get_most_likely_key()
    message1 = a.decipher()
    print(message1)
    print("key is :",a.key)

这个样例的执行结果如下:

a declaration of the independence of cyberspace
by john perry barlow
governments of the industrial world, you weary giants of flesh and steel, i come from cyberspace, the new home of mind. on behalf of the future, i ask you of the past to leave us alone. you are not welcome among us. you have no sovereignty where we gather.
we have no elected government, nor are we likely to have one, so i address you with no greater authority than that with which liberty itself always speaks. i declare the global social space we are building to be naturally independent of the tyrannies you seek to impose on us. you have no moral right to rule us nor do you possess any methods of enforcement we have true reason to fear.
governments derive their just powers from the consent of the governed. you have neither solicited nor received ours. we did
not invite you. you do not know us, nor do you know our world. cyberspace does not lie within your borders. do not think that you can build it, as though it were a public construction project. you cannot. it is an act of nature and it grows itself
through our collective actions.
you have not engaged in our great and gathering conversation, nor did you create the wealth of our marketplaces. you do not
know our culture, our ethics, or the unwritten codes that already provide our society more order than could be obtained by any of your impositions.
you claim there are problems among us that you need to solve. you use this claim as an excuse to invade our precincts. many
of these problems don't exist. where there are real conflicts, where there are wrongs, we will identify them and address them by our means. we are forming our own social contract. this governance will arise according to the conditions of our world, not yours. our world is different.
cyberspace consists of transactions, relationships, and thought itself, arrayed like a standing wave in the web of our communications. ours is a world that is both everywhere and nowhere, but it is not where bodies live.
we are creating a world that all may enter without privilege or prejudice accorded by race, economic power, military force,
or station of birth.
we are creating a world where anyone, anywhere may express his or her beliefs, no matter how singular, without fear of being coerced into silence or conformity.
your legal concepts of property, expression, identity, movement, and context do not apply to us. they are all based on matter, and there is no matter here.
our identities have no bodies, so, unlike you, we cannot obtain order by physical coercion. we believe that from ethics, enlightened self-interest, and the commonweal, our governance will emerge. our identities may be distributed across many of your jurisdictions. the only law that all our constituent cultures would generally recognize is the golden rule. we hope we will be able to build our particular solutions on that basis. but we cannot accept the solutions you are attempting to impose.
in the united states, you have today created a law, the telecommunications reform act, which repudiates your own constitution and insults the dreams of jefferson, washington, mill, madison, detoqueville, and brandeis. these dreams must now be born
anew in us.
you are terrified of your own children, since they are natives in a world where you will always be immigrants. because you fear them, you entrust your bureaucracies with the parental responsibilities you are too cowardly to confront yourselves. in
our world, all the sentiments and expressions of humanity, from the debasing to the angelic, are parts of a seamless whole,
the global conversation of bits. we cannot separate the air that chokes from the air upon which wings beat.
in china, germany, france, russia, singapore, italy and the united states, you are trying to ward off the virus of liberty by erecting guard posts at the frontiers of cyberspace. these may keep out the contagion for a small time, but they will not
work in a world that will soon be blanketed in bit-bearing media.
your increasingly obsolete information industries would perpetuate themselves by proposing laws, in america and elsewhere, that claim to own speech itself throughout the world. these laws would declare ideas to be another industrial product, no more noble than pig iron. in our world, whatever the human mind may create can be reproduced and distributed infinitely at no cost. the global conveyance of thought no longer requires your factories to accomplish.
these increasingly hostile and colonial measures place us in the same position as those previous lovers of freedom and self-determination who had to reject the authorities of distant, uninformed powers. we must declare our virtual selves immune to
your sovereignty, even as we continue to consent to your rule over our bodies. we will spread ourselves across the planet so that no one can arrest our thoughts.
we will create a civilization of the mind in cyberspace. may it be more humane and fair than the world your governments have made before.
flag is mrctf vigenere crypto crack man, please add underscore and curly braces.
key is : gsfepngsfepngsfepn

posted @ 2022-08-09 15:59  01am  阅读(1002)  评论(0编辑  收藏  举报