密码溢出

时间:2012-11-15 23:10:33

标签: c

我正在加密如下,但是如果它们移出范围之外不知道如何阻止大写字母进入其他符号,同样小写字母超出小写字母的范围。如何让它们围成一圈并停止溢出?感谢

    int size = strlen(plain_text);
int arrayelement = 0;
for(arrayelement = 0; arrayelement < size; arrayelement++)
{
    if (islower(plain_text[arrayelement]))
    {
        ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey);
    }
    else if (isupper(plain_text[arrayelement]))
    {
        ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey);
    }
}

ciphered_text[size] = '\0';
printf("%s", ciphered_text);

4 个答案:

答案 0 :(得分:1)

我猜你使用像char这样的类型,所以很容易解决不溢出的问题

int tmp_ciphered = (my_char + shift) % 0xff;
char ciphered = (char)(tmp_ciphered);
然后你转身不要溢出,这是一个戒指

答案 1 :(得分:1)

这个重复(几乎完全)c++ simple Caesar cipher algorithm

请注意,我不同意该帖子上接受的答案。基本上你必须使用像((c-'a'+ shift)%26)+'a'之类的东西将角色映射到范围内。但是假设你的角色是'a'..'z'。可能更安全使用c&gt; ='a'&amp;&amp; c&lt; ='z'而不是islower,因为我不确定语言环境将如何在非英语系统上发挥作用。类似于isupper和其他范围。最后,当char不在任何范围内时,您需要一个else子句来处理。

答案 2 :(得分:1)

唯一真正可移植的方法是为输入域构建查找表,并根据非线性假设手动构建字符。

即使对于['a'..'z','A'..'Z']的受限域,假设'A'..'Z'是连续的,由语言标准定义,并且可能并非总是如此。对于任何反其道而行之的反对者,我会引导你到图表at this link中字符的序数位置,密切注意假定序列中间的死区。如果您认为“没有人再使用EBCDIC了”,请允许我向您保证AS / 400和OS / 390都很活跃(并且可能正在处理您的美国税收,因为IRS是IBM最大的客户之一)。

事实上,C标准对此非常明确:

  

C99-5.2.1.3 在源和执行基本字符集中,上述十进制数字列表中0之后的每个字符的值应比前一个值大1。

在字符集的任何其他部分中,甚至没有提到定义的排序或甚至隐含的排序。实际上,'0'..'9'还有一个独特的属性:它们是唯一保证不受区域设置更改影响的字符。

因此,不要假设人物在标准的可疑沉默中掠过我们的鼻子时存在线性延续,让我们定义我们自己的地图。我不会像往常一样在这里内联代码;如果你还在我身边,你真的很有兴趣知道,并且可能会阅读和批评下面的代码。但我将概述它的工作原理:

  1. 静态声明两个字母,长度加倍(A..ZA..Z,a..za..z)。
  2. 声明两个数组(加密和解密)足够大以容纳(1<<CHAR_BIT)条目。
  3. 使用与其索引对应的值完全初始化两个数组。例如:a[0]=0a[1]=1,...
  4. 使用与移位宽度Ex相对应的适当值填充来自(1)的字母表中加密数组中的每个位置。对于ROT5 a['a'] = 'g'
  5. 镜子(4)通过应用相反的移位方向从字母表的尾部向后工作。例如:'a ['g'] ='a';
  6. 您现在可以将加密数组用作简单表格,将输入文本转换为密文:

    enc-char = encrypt[ dec-char ];
    dec-char = decrypt[ enc-char ];
    

    如果您认为仅仅为了获得源级平台独立性似乎需要大量工作,那么您绝对是正确的。但是你会在#ifdef #endif 地狱中感到惊讶,人们试图将其作为“多平台”传递出去。与平台无关的代码的核心目标不仅是定义通用源,还要定义行为。无论平台如何,上述概念都将起作用。 (而不是#ifdef)。

    感谢您抽出宝贵时间阅读此次惨败。这个看似简单的问题......


    示例main.cpp

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <string.h>
    
    // global tables for encoding. must call init_tables() before using
    static char xlat_enc[1 << CHAR_BIT];
    static char xlat_dec[1 << CHAR_BIT];
    
    void init_tables(unsigned shift)
    {
        // our rotation alphabets
        static char ucase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
        static char lcase[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
        int i=0;
    
        // ensure shift is below our maximum shift
        shift %= 26;
    
        // prime our table
        for (;i<(1 << CHAR_BIT);i++)
            xlat_enc[i] = xlat_dec[i] = i;
    
        // apply shift to our xlat tables, both enc and dec.
        for (i=0;i<(sizeof(ucase)+1)/2;i++)
        {
            xlat_enc[ lcase[i] ] = lcase[i+shift];
            xlat_enc[ ucase[i] ] = ucase[i+shift];
            xlat_dec[ lcase[sizeof(lcase) - i - 1] ] = lcase[sizeof(lcase) - i - 1 - shift];
            xlat_dec[ ucase[sizeof(ucase) - i - 1] ] = ucase[sizeof(ucase) - i - 1 - shift];
        }
    }
    
    
    // main entrypoint
    int main(int argc, char *argv[])
    {
        // using a shift of 13 for our sample
        const int shift = 13;
    
        // initialize the tables
        init_tables(shift);
    
        // now  drop the messsage to the console
        char plain[] = "The quick brown fox jumps over the lazy dog.";
        char *p = plain;
        for (;*p; fputc(xlat_enc[*p++], stdout));
        fputc('\n', stdout);
    
        char cipher[] = "Gur dhvpx oebja sbk whzcf bire gur ynml qbt.";
        p = cipher;
        for (;*p; fputc(xlat_dec[*p++], stdout));
        fputc('\n', stdout);
    
        return EXIT_SUCCESS;
    }
    

    <强>输出

    Gur dhvpx oebja sbk whzcf bire gur ynml qbt.
    The quick brown fox jumps over the lazy dog.
    

答案 3 :(得分:0)

你可以按字面意思实现它:

“如果他们被移出范围”:

if (ciphered_text[arrayelement] > 'z')

“让它们围成一圈并停止溢出”:

ciphered_text[arrayelement] -= 26;

在您的背景下:

if (plain_text[arrayelement] >= 'a' && plain_text[arrayelement] <= 'z')
{
    ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey);
    if (ciphered_text[arrayelement] > 'z')
        ciphered_text[arrayelement] -= 26;
}

(假设您使用ACSII编码中的英文文本,而shiftkey的范围是1 ... 25,就像它应该的那样)