简单的单字节数组加密需要人工长数组才能工作?

时间:2017-05-11 16:21:35

标签: c arrays encryption

在单个char阵列上运行简单加密。当数组大小小于或等于1时,它似乎不起作用,即使只有一个char正在改变。

以下情况有效,因为yesCrypto[10]设置为10(或> 1)。

char noCrypto[] = "H";    //sets an array to hold unencrypted H
char yesCrypto[10];        //sets array to hold encrypted H

yesCrypto[0]=noCrypto[0]+1;              
//takes 'H' from noCrypto and turns it into an 'I' and moves it into yesCrypto.

printf("Encrypted string is '%s'\n", yesCrypto);        
//prints Encrypted version of 'H', 'I'

以下内容不起作用,因为yesCrypto[0]设置为0,设置为1时也不起作用。

char noCrypto[] = "H";    //sets an array to hold unencrypted H
char yesCrypto[1];        //sets array to hold encrypted H

yesCrypto[0]=noCrypto[0]+1;              
//takes 'H' from noCrypto and turns it into an 'I' and moves it into yesCrypto.

printf("Encrypted string is '%s'\n", yesCrypto);        
//prints 'IH'

附带问题:为什么在它不工作时打印IH。

2 个答案:

答案 0 :(得分:3)

代码正在尝试使用const React = require('react-native'); const { Dimensions } = React; const deviceHeight = Dimensions.get('window').height; const deviceWidth = Dimensions.get('window').width; export default { webview: { width: deviceWidth, height: deviceHeight } }; 打印不是字符串的字符数组。

"%s"当然不会 null character 终止。

yesCrypto[]

相反,限制打印或附加空字符

char yesCrypto[10];
yesCrypto[0] = noCrypto[0]+1; 
printf("Encrypted string is '%s'\n", yesCrypto); // bad

OP的第二个代码很糟糕,因为长度为0的对象数组缺乏定义的行为。

// 1 is the maximum number of characters to print
printf("Encrypted string is '%.*s'\n", 1, yesCrypto);
// or 
yesCrypto[1] = '\0'; 
printf("Encrypted string is '%s'\n", yesCrypto);

OP编辑的帖子使用// bad char yesCrypto[0]; 。在那种情况下使用

char yesCrypto[1];

基本上,将加密数据打印为字符串是一个问题,因为加密字符数组可能在许多地方包含空字符字符串需要空字符并以第一个字符结束。

答案 1 :(得分:2)

在第一种情况下,您将提供一个非空终止的数组(作为%s的参数)。

引用C11,章节§7.21.6.1,

  

s

     

如果不存在l长度修饰符,则参数应为指向初始值的指针   字符类型数组的元素。 280) 数组中的字符是   写入(但不包括)终止空字符。如果   指定精度,不超过写入的多个字节。 如果   精度未指定或大于数组的大小,数组应   包含空字符。

在这种情况下,yesCrypto是一个自动本地数组并且未初始化,内容是不确定的,因此无法保证数组中存在空值。因此使用情况会导致undefined behavior

您在第二种情况下看到的内容也是undefined behavior

引用C11,章节§6.7.6.2

  

除了可选的类型限定符和关键字static之外,[]可能会划界   表达式或*。如果它们分隔表达式(指定数组的大小),则   表达式应具有整数类型。 如果表达式是常量表达式,它应该是   值大于零。 [...]

因此,后面的代码(包含char yesCrypto[0];)违反了Constraints,它会调用UB。

关于为什么这可能产生编译错误的说明:

gcc does have an extension支持zer-length数组,但用例非常具体,自C99以来,“灵活数组成员”是此扩展的标准选择。

最后,

  

...设置为1时也不起作用。

将缺少空终止符的空间,引发与第一种情况相同的问题。换句话说,要使char数组的行为类似于包含n元素的字符串,您需要

  • 数组的大小为n+1
  • index n包含空字符('\0')。