0

我正在制作一个程序来实现异或加密,在玩弄我的程序时,我输入了各种组合键,程序运行良好,直到我输入键值:904932,这会导致省略“d”字符,例如,如果我输入“嗨,我的名字”是dexter,我讨厌edit1中的愚蠢妹妹dede',加密和解密回来将使我的edit1文本:'嗨,我的名字是exter,我讨厌我的愚蠢妹妹ee'这是怎么回事?

procedure TForm2.Button1Click(Sender: TObject);
    var
     c:char;
     i,key: integer;
    begin
      s := edit1.Text;
       edit1.Text := #0;
       key := strtoint(edit2.text);
       key := key + 128;//i am adding 128  so that i dont get NULL char 
       for I := 1 to length(s)  do {or 0 to lenght(s)? i dont know}
      begin
       c := s[i];
       c := char(ord(c) xor key);
       edit1.Text :=  edit1.Text + c;
      end;
    end;
4

4 回答 4

5

添加 128 不会解决您的问题。它只是移动它。

您的“异或键”只是异或键的最后一个字节,即在您的 904932 的情况下为 $E4。$E4+128 将四舍五入(即-256)为字节值 100,即“d”的 ASCII 值. 这就是你的“d”消失的原因。

所以我想如果你想显示加密的文本,不应该使用这样的异或算法。我建议你做一些简单的排列算法。

于 2010-08-28T15:51:12.383 回答
2

我实际上建议使用像 AES-CBC 这样的现代密码学,但如果你想玩复古密码学,那么让我们在这里玩得开心。由于您的加密输出是文本,我可能建议使用加法模而不是 XOR。仅在处理字节时使用 XOR,而不是字符。您需要避免输出中的某些特殊字符。在这种情况下,您似乎遇到了 NULL 字符的问题。您可以通过定义字符集来避免输出字符。
例如,您可能只想使用 ASCII 值 1 到 127 范围内的字符(除 NULL 之外的所有 ASCII 字符)。这意味着底数为 1,模数为 126 = (127 - 1)

要对字符进行编码,首先要减去基数。添加键值。然后,得到模数结果。最后,重新添加底座。

小写字母 d 的十进制值为 100。
100 - 1 = 99 // 减去基数
99 + 904932 = 905031 // 加上键值,这里使用你的
905031 % 126 = 99 // 模数结果 lol 904932 % 126 = 0
99 + 1 = 100 // 加回基数

由于您的键值可被模数 126 整除,因此输出等于输入。

取消加法模是一个稍微不同的过程。
100 - 1 = 99 // 减去基数
99 - 904932 = -904833 // 减去键值
-904833 % 126 = -27 // 模数结果
126 + -27 = 99 // 将模数加到模数结果中
99 + 1 = 100 // 添加基础

您可以将模数设置得尽可能高,以便在字符集中包含尽可能多的字符,并且通过一些花哨的数学运算,您可以以任何方式将字符映射到整数值。

虽然我确实说您可以以任何您想要的方式映射字符,但事实是您受到文本写入的媒体的限制。您不能将模数设置为高于媒体可以携带的所有字符的总数,但您可以为编码和解码值设置单独的字符映射。

我还将评论您的键值选择。对所有字符应用相同的密钥值几乎是最弱的加密形式。(ROT13 真的可以被认为是加密吗?)想出一些方法来改变每个字符的密钥值。使用这种类型的加密时所做的事情是为每个字符将密钥增加一些值,或者将处理后的字符的值添加到密钥中。

于 2010-08-30T08:53:06.850 回答
1

即使结果字符是#0,使用 XOR 也没有问题,因为$00 xor $E4 = $E4它揭示了原始字符。问题是您将加密结果用作专门处理 #0 的字符串。如果您将加密字符串指定为字节数组,您应该没问题。如果要显示它,请使用 BinToHex 或 IntToHex 序列。

于 2010-08-28T15:32:00.500 回答
1

这是给你的修订版。

procedure TForm2.Button1Click(Sender: TObject); 
var 
  i,key: integer; 
begin 
  s := edit1.Text; 
  edit1.Text := ''; 
  key := strtoint(edit2.text); 
  if Key = 0 then //replacement for the +128
    Key := 128
  for I := 1 to length(s)  do //string are 1 indexed.  Dynamic arrays 0 indexed. 
  begin 
    s[i] := char(s[i] xor key);  
  end; 
  edit1.Text :=  S; //Much faster to assign a full string than to assign character by character.  
                    //Also, this might fix your vanishing "d" problem.
                    //I didn't test it, but I suspect that
                    //edit1.Text + c might result in no change if c=#0
end; 
于 2010-08-29T16:33:01.487 回答