趣题分享[5] -- 古典密码 相关题目

可通过优化代码的方式打表,但这里只给出以古典方式分析题目

确认 csecrets 的对应关系(使得可以通过 c 恢复 secrets

确认 Time_Machine() 的单调性(使得可以根据大小关系推断)

词频分析(找出空格、e的对应值)

特判(Case)

枚举状态、NLP 处理小技巧、使用等宽字体、使用辅助函数恢复(磨刀不误砍柴工)、生成 ASCII 码表、生成多种排序方式、生成 Key Value Pair,且使用 Tuple 来实现更多展示信息,方便分析

from collections import Counter


c = [11827965311995932558558, 436740119853412116456, 41650252425798979676175, 50626127671556204573190, 41650252425798979676175, 60980101311350323854180, 963563059779422880492, 75413523978530416956915, 436740119853412116456, 43341417116799148415475, 86365877055447093121710, 65537436405378983697036, 43341417116799148415475, 40009068720753857066727, 75413523978530416956915, 436740119853412116456, 89280922053913796530170, 63227978177791478672610, 78047807265358355987991, 436740119853412116456, 75413523978530416956915, 63227978177791478672610, 436740119853412116456, 72846494790687055657395, 63227978177791478672610, 56664683419644282294873, 80750509186740318135738, 43341417116799148415475, 436740119853412116456, 58792701246489673616637, 89280922053913796530170, 436740119853412116456, 65537436405378983697036, 78047807265358355987991, 92269143789218304195771, 92269143789218304195771, 56664683419644282294873, 43341417116799148415475, 436740119853412116456, 36872675850292365936996, 48724893081131391463482, 43341417116799148415475, 36872675850292365936996, 41650252425798979676175, 436740119853412116456, 63227978177791478672610, 45083567393314209309726, 436740119853412116456, 75413523978530416956915, 50626127671556204573190, 58792701246489673616637, 43341417116799148415475, 1864884862832210879220, 436740119853412116456, 11827965311995932558558, 436740119853412116456, 43341417116799148415475, 86365877055447093121710, 65537436405378983697036, 43341417116799148415475, 40009068720753857066727, 75413523978530416956915, 436740119853412116456, 75413523978530416956915, 48724893081131391463482, 43341417116799148415475, 436740119853412116456, 65537436405378983697036,
     70345565162259426664317, 63227978177791478672610, 46877717850904608344028, 70345565162259426664317, 36872675850292365936996, 58792701246489673616637, 436740119853412116456, 75413523978530416956915, 63227978177791478672610, 436740119853412116456, 70345565162259426664317, 78047807265358355987991, 60980101311350323854180, 436740119853412116456, 45083567393314209309726, 63227978177791478672610, 70345565162259426664317, 436740119853412116456, 89280922053913796530170, 43341417116799148415475, 36872675850292365936996, 70345565162259426664317, 72846494790687055657395, 1561103367493488746697, 8905422223361768646663, 7434854394795874666620, 19766534787409257458523, 8393017568869581586191, 20736491520823134042987, 10000251324957046694310, 95331756776933061303633, 89280922053913796530170, 2210983036628738475708, 78047807265358355987991, 33924401628947906025510, 54594963263249504183781, 60980101311350323854180, 2210983036628738475708, 83522804274246348745272, 33924401628947906025510, 75413523978530416956915, 50626127671556204573190, 58792701246489673616637, 43341417116799148415475, 33924401628947906025510, 40009068720753857066727, 2210983036628738475708, 58792701246489673616637, 65537436405378983697036, 56664683419644282294873, 43341417116799148415475, 86365877055447093121710, 50626127671556204573190, 75413523978530416956915, 89280922053913796530170, 33924401628947906025510, 80750509186740318135738, 43341417116799148415475, 70345565162259426664317, 89280922053913796530170, 33924401628947906025510, 83522804274246348745272, 43341417116799148415475, 2401069164267674760552, 2401069164267674760552, 493945107805384908948, 101685064551886104386625]
print(f'clist的长度位{len(c)}')
根据出现频率排序 = sorted(c, key=c.count, reverse=True)
print('根据出现频率排序 = ' + str(根据出现频率排序))

c统计数量 = Counter(根据出现频率排序)
c统计数量 = sorted(c统计数量.items(), key=lambda x: x[0])


def show_list(数据表, 每行n个):
    print('根据值大小排序 数值:出现次数\t表名:c统计数量')
    for i in range(0, len(数据表), 每行n个):
        print(数据表[i:i + 每行n个])


show_list(c统计数量, 4)


def find_index(传入list, 要查询的值):
    索引 = [index for index, (value, count) in enumerate(
        传入list) if value == 要查询的值]

    if 索引:
        print(f'\n值 {要查询的值} 的索引为: {索引[0] + 1}')
    else:
        print(f'\n值 {要查询的值} 未在列表中找到')


def ascii_print_table_number_axis(chars_per_row=10):
    ascii_chars = [chr(i) for i in range(32, 127)] 
    ascii_chars.sort()

    for i in range(0, len(ascii_chars), chars_per_row):
        row = ascii_chars[i:i + chars_per_row]
        for j, char in enumerate(row):
            char_index = ord(char)
            print(f'{char}: {char_index}', end='\t')
        print() 
    
ascii_print_table_number_axis(chars_per_row=10)

find_index(c统计数量, 33924401628947906025510) 


def transform_to_dict_with_counts_and_chars(c统计数量):
    result_dict = {}

    for item in c统计数量:
        value = item[0]
        count = item[1]
        char_to_replace = '*'  # 可以替换为想要的字符

        if value == 436740119853412116456:
            char_to_replace = ' '  # 出现次数多且ascii小
        if value == 43341417116799148415475:
            char_to_replace = 'e'

        if value == 8905422223361768646663:
            char_to_replace = 'D'
        if value == 7434854394795874666620:
            char_to_replace = 'A'
        if value == 19766534787409257458523:
            char_to_replace = 'S'
        if value == 8393017568869581586191:
            char_to_replace = 'C'
        if value == 20736491520823134042987:
            char_to_replace = 'T'
        if value == 10000251324957046694310:
            char_to_replace = 'F'
        if value == 95331756776933061303633:
            char_to_replace = '{'
        if value == 101685064551886104386625:
            char_to_replace = '}'

        # 恢复e前
        if value == 41650252425798979676175:
            char_to_replace = 'd'
        if value == 40009068720753857066727:
            char_to_replace = 'c'
        if value == 36872675850292365936996:
            char_to_replace = 'a' 
        if value == 2401069164267674760552:
            char_to_replace = '1'
        if value == 2210983036628738475708:
            char_to_replace = '0'
        if value == 963563059779422880492:
            char_to_replace = '\''
        if value == 11827965311995932558558:
            char_to_replace = 'I'
        if value == 33924401628947906025510:
            char_to_replace = '_'
        if value == 1561103367493488746697:
            char_to_replace = ','
        if value == 1864884862832210879220:
            char_to_replace = '.'
        if value == 493945107805384908948:
            char_to_replace = '!' 

        result_dict[value] = (count, char_to_replace)

    return result_dict


processed_dict = transform_to_dict_with_counts_and_chars(c统计数量)
print('\n以value大小对processed_dict排序')


def show_dict(processed_dict, items_per_row=3):
    items = list(processed_dict.items())
    for i in range(0, len(items), items_per_row):
        row = items[i:i + items_per_row]
        for key, (count, char_to_replace) in row:
            print(f'{key}: ({count}, "{char_to_replace}"),', end='\t')
        print()


def find_enc(查询的字符):
    加密的值 = None
    for key, (count, char) in processed_dict.items():
        if char == 查询的字符:
            加密的值 = key
            return 加密的值


def recover_begin_e(processed_dict):
    print('\n待处理字典')
    show_dict(processed_dict)
    e = find_enc('e')
    开花括号 = find_enc('{')
    miniEZ = ''
    for i in range(ord(b'e') + 1, ord(b'z') + 1):
        miniEZ += chr(i)
    print(f'{miniEZ = }')
    print(len(miniEZ))
    miniEZ = miniEZ.replace('q', '')
    miniEZ = miniEZ.replace('j', '')

    miniAE = ''
    for i in range(ord(b'a'), ord(b'e')):
        miniAE += chr(i)
    print(f'{miniAE = }')

    result_dict = {}
    tempEZ = miniEZ  # 备份
    for item in c统计数量:
        value = item[0]
        count = item[1]
        if value > e and value < 开花括号:
            char_to_replace = tempEZ[0]
            tempEZ = tempEZ[1:]
            result_dict[value] = (count, char_to_replace)
        else: 
            result_dict[value] = (count, processed_dict[value][1])

    return result_dict


dic = recover_begin_e(processed_dict)
processed_dict = dic 


show_dict(processed_dict)


def sort_dict_by_count(processed_dict):
    return sorted(processed_dict.items(), key=lambda x: x[1][0], reverse=True)


print('\n以count对processed_dict排序')
sorted_dict = sort_dict_by_count(processed_dict)


show_dict(dict(sorted_dict)) 

def translate_with_dict(c, processed_dict):
    result = ''
    for item in c:
        if item in processed_dict:
            result += processed_dict[item][1]
    return result

def 去重排序得到原始递增list_翻译得到原始明文(c):
    c = list(set(c))
    c.sort()
    result = translate_with_dict(c, processed_dict)
    return result


print(f'\n题目原始明文\n{去重排序得到原始递增list_翻译得到原始明文(c)}')
result = translate_with_dict(c, processed_dict)
print(f'\n题目预期排序方式\n{result}')