【问题标题】:How to cipher a text in C?如何在 C 中加密文本?
【发布时间】:2012-04-14 11:38:07
【问题描述】:

我正在解决一个问题,但我有点卡住了,所以我想寻求您的帮助。我想制作一个具有以下功能的程序。用户将给出一个 4 位数的密钥和一个文本。

然后将使用以下方法将文本转换为密码。 假设文本输入是“ABC”,密钥是 123。然后,使用 ASCII 表,“ABC”将转换为“BDF”。文本将在 ASCII 表中向前移动 K 个位置,其中 K 是键的对应数字。考虑文本无限。我的第一个动作是将密钥转换为数组。

//scanning the cypher key
scanf("%d", &cypherkey);

//converting the cypher key into an array using a practical mathematic method for extracting its digit
int keyarray[4];
keyarray[0]= cypherkey/1000;
keyarray[1]= (cypherkey-keyarray[0]*1000)/100;
keyarray[2]= ((cypherkey-keyarray[0]*1000)- keyarray[1]*100)/10;
keyarray[3]= ((cypherkey-keyarray[0]*1000)- keyarray[1]*100)-keyarray[2]*10;

所以,现在我有一个数组中的键。但是,我找不到阅读文本然后对其进行加密的好方法。我不能使用数组,因为我们不知道文本的长度。

如果有任何帮助,我将不胜感激!

【问题讨论】:

  • 循环读取文本,一次一个字符。
  • 如果是homework,你应该这样标记它!
  • 如果不是家庭作业,你不应该发明自己的密码——尤其是不那么明显的弱密码!
  • 抱歉回复晚了,是的,这是我的编程课作业。我马上更新标签。

标签: c cryptography


【解决方案1】:

忽略所有性能问题,最直接的答案是一次只处理一个字符。

基本上,

  1. 从您的输入中读取一个字符。
  2. 根据您的算法和当前的“关键数字”对其进行转换
  3. 提升您在按键阵列中的位置,必要时循环播放
  4. 重复直到输入结束

出于性能原因,现实世界的实现可能会将输入读入缓冲区,对整个缓冲区进行操作,然后重复。

【讨论】:

    【解决方案2】:

    我拍了一张照片,输入文本在应用程序中进行了硬编码。下面的示例不是生产代码,仅用于教育目的。

    我的方法有两个挑战:

    • 编写计算数字中有多少位的函数:

    • 实现检索特定数字的函数;

    .

    #include <stdio.h>
    #include <string.h>
    
    int count_digits(int number) // // http://stackoverflow.com/questions/1489830/efficient-way-to-determine-number-of-digits-in-an-integer
    {
        int digits = 0;
        if (number < 0) 
        digits = 1; 
    
        while (number) 
        {
            number /= 10;
            digits++;
        }
    
        return digits;
    }
    
    char get_digit(int number, int index) // starts at index 0
    {
        if (number == 0)
            return (char)0;
    
        int n_digits = count_digits(number);
        if (index > n_digits)
            return (char)-1;
    
        char digit = -1;
        int i;
            for (i = 0; i < (n_digits-index); i++)
        {
            digit = number % 10;
            number /= 10;
        }
    
        return digit;   
    }
    
    int main()
    {
        printf("* Type the encoding key (numbers only): ");
        int key = 0;
        scanf("%d", &key);
    
        int key_digits = count_digits(key);
        //printf("* The key has %d digits.\n", key_digits);
    
        char input_msg[] = "ABCABC"; // This is the input text
        int input_sz = strlen(input_msg);
        //printf("* Input message [%s] has %d characters.\n", input_msg, input_sz);
    
        int i, d = 0;   
        for (i = 0; i < input_sz; i++)
        {       
            if (d >= key_digits)
                d = 0;
    
            input_msg[i] += get_digit(key, d);      
            d++;
        }
    
        printf("* Encoded text is: %s\n", input_msg);
    
        return 0;
    }
    

    输出以下内容...

    对于输入文本ABC

    $ ./cypher 
    * Type the encoding key (numbers only): 123
    * Encoded text is: BDF
    
    $ ./cypher 
    * Type the encoding key (numbers only): 234
    * Encoded text is: CEG
    

    对于输入文本ABCABC

    $ ./cypher 
    * Type the encoding key (numbers only): 123
    * Encoded text is: BDFBDF
    

    【讨论】:

      【解决方案3】:

      我相信有一种更简单的方法可以做到这一点。您描述的算法被称为广义凯撒密码。密文的同余关系是 C = rP + s (mod 26) 其中 P 是纯文本,r 是乘数,s 是移位。在您描述的情况下,您的乘数为 2,移位为 1。如果您想避免使用表格,您可以获取纯文本中每个字母的 unicode,然后从 unicode 中减去一致的偏移量,这样你总是得到一个小于 26 的数字。要破译密文,你需要将密文乘以 r 的模逆加上你应用的偏移量,然后从数字 unicode 表示中转换回字符。

      简而言之,您需要获取一个字符的 unicode,减去一些偏移量,乘以 2,加 2 并取该数字的 mod 26 来加密。

      要反转这个过程,将密文减去 1 乘以模逆,加上偏移量并转换回字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 1970-01-01
        • 2013-05-31
        • 2016-03-11
        • 2020-06-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多