buuctf.crypto.摩丝

发布时间 2023-03-23 22:41:57作者: redqx

一道摩斯密码
基于单表替换的
原理很简单......
但是摩斯密码在对照表上不是很完善,导致一些特殊的字符没有统一的规定
也就是说,原理一样,但是采用不同的对照表加密的结果是不一样的

另外说一下摩斯密码对照表的生成是根据字母出现的频率来决定的(chatgpt说的)
下面是我自己写的一个简单的摩斯密码加密解密,不可和网上的在线网站相提并论
因为在线网站的对照表我都不知道

#include<stdio.h> 
#include<string.h>
#include<stdlib.h>
 
struct msDit 
{
    char ascii;
    char* lpms;
};
struct my_node 
{
    struct my_node* next;
    char* data;
};
char toupper(char c)
{
    if ((c >= 'a') && (c <= 'z'))
        return c + ('A' - 'a');
    return c;
}
void table2index(struct msDit* t,int tlen, char* input, int ilen)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < ilen; i++)
    {
        for (j = 0; j < tlen; j++)
        {
            if (toupper(input[i]) == t[j].ascii)
            {
                input[i] = (char)j;
                break;
            }
        }
    }
    return;
}
char* string2index(struct msDit* t, int tlen,char* input)
{
    int i = 0,j=0;
    char* lp = malloc(0x100);
    int everyLen = 0;
    memset(lp, 0, 0x100);
    while(1)
    {

        if (*input==0)
        {
            break;
        }
        for (everyLen = 0; ; everyLen++)
        {
            if (input[everyLen] == ' ' || input[everyLen] == 0)
                break;
        }

        for (j = 0; j < tlen; j++)
        {
            if (strlen(t[j].lpms) == everyLen)//要2个人的长度都相等才能比,否则会没有意义,别人故意截断某一部分和你比较
            {
                if (!memcmp(t[j].lpms, input, everyLen))
                {
                    //说明它找打了
                    lp[i] = (char)j + 1;
                    input += everyLen;
                    if (*input == ' ')
                        input++;//指向下一个开始的位置,如果下一位不是' '而是0,我们就不用++了
                    i++;
                    break;
                }
            }
            
        }   
    }
    return lp;
}
char* fenc(struct msDit* dict,int tlen,char* input)//把输入换做索引.然后
{
    int ilen = strlen(input);
    int i = 0;
    char* lp = malloc(ilen * 16 + 1);
    memset(lp, 0, ilen * 16 + 1);
    table2index(dict,tlen, input, ilen);
    for (i = 0; i < ilen; i++)
    {
        strcat(lp, dict[input[i]].lpms);
        strcat(lp, " ");//作为分割的存在
    }
    return lp;
}
char* fdec(struct msDit* dict, int tlen,char* input)//把输入换做索引.然后
{
    int i = 0;
    char* lp;
    lp=string2index(dict, tlen,input);
    for (i = 0; lp[i] ; i++)
    {   
        lp[i] = dict[lp[i] - 1].ascii;//为了循环的退出,我们的基数是1,然后0用于退出循环
    }
    return lp;
}
int	 main()
{
    // 摩斯密码对照表
    struct msDit morseTable[] = 
    {
        {'A', ".-"},
        {'B', "-..."},
        {'C', "-.-."},
        {'D', "-.."},
        {'E', "."},
        {'F', "..-."},
        {'G', "--."},
        {'H', "...."},
        {'I', ".."},
        {'J', ".---"},
        {'K', "-.-"},
        {'L', ".-.."},
        {'M', "--"},
        {'N', "-."},
        {'O', "---"},
        {'P', ".--."},
        {'Q', "--.-"},
        {'R', ".-."},
        {'S', "..."},
        {'T', "-"},
        {'U', "..-"},
        {'V', "...-"},
        {'W', ".--"},
        {'X', "-..-"},
        {'Y', "-.--"},
        {'Z', "--.."},
        {'0', "-----"},
        {'1', ".----"},
        {'2', "..---"},
        {'3', "...--"},
        {'4', "....-"},
        {'5', "....."},
        {'6', "-...."},
        {'7', "--..."},
        {'8', "---.."},
        {'9', "----."},
        {'.', ".-.-.-"},
        {',', "--..--"},
        {'?', "..--.."},
        {'!', "-.-.--"},
        {'/', "-..-."},
        {'{', "-.--."},
        {'}', "-.--.-"},
        {'&', ".-..."},
        {':', "---..."},
        {';', "-.-.-."},
        {'=', "-...-"},
        {'+', ".-.-."},
        {'-', "-....-"},
        {'_', "..--.-"},
        {'"', ".-..-."},
        {'$', "...-..-"},
        {'@', ".--.-."},
        {' ', " "},
    };
    char flag[] = "flag{QWER5008_IS_MY_Home}";
    char enc[] = "..-. .-.. .- --. -.--. --.- .-- . .-. ..... ----- ----- ---.. ..--.- .. ... ..--.- -- -.-- ..--.- .... --- -- . -.--.-";
    char * lp1 ,*lp2;

    lp1 = fenc(morseTable, sizeof(morseTable) / sizeof(struct msDit), flag);
    printf("%s\n", lp1);

    lp2 = fdec(morseTable, sizeof(morseTable) / sizeof(struct msDit), enc);
    printf("%s\n", lp2);
	return 0;
}


..-. .-.. .- --. -.--. --.- .-- . .-. ..... ----- ----- ---.. ..--.- .. ... ..--.- -- -.-- ..--.- .... --- -- . -.--.-
FLAG{QWER5008_IS_MY_HOME}

E:\C\2022\C1\Debug\C1.exe (进程 18760)已退出,代码为 0。
按任意键关闭此窗口. . .