我正在制作一个程序来实现xor加密,在玩我的程序时,我输入了各种组合键,程序运行正常,直到我输入键值904932,这导致了'd'字符的省略,例如,如果我输入'嗨,我的名字是德克斯特,我讨厌我在编辑1中的愚蠢姐妹dede',加密和解密将 让我的edit1文字:'嗨,我的名字是exter,我讨厌我的stupi姐姐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;
答案 0 :(得分:5)
添加128无法解决您的问题。它只是移动它。
你的“xor键”只是你键的最后一个字节,在904932的情况下是$ E4。 $ E4 + 128将被舍入(即-256)到字节值100,这是ASCII值“d”。 这就是你的“d”消失的原因。
所以我想如果要显示加密文本,不应该使用这样的xor算法。 我建议你做一些简单的置换算法。
答案 1 :(得分: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真的可以被认为是加密吗?)想办法改变每个角色的键值。使用这种类型的加密时所做的事情是将每个字符的键增加一些值,或者将处理后的字符值添加到键中。
答案 2 :(得分:1)
即使生成的字符为#0,使用XOR也没问题,因为$00 xor $E4 = $E4
显示原始字符。问题是您使用加密结果作为特殊处理#0的字符串。如果将加密的字符串指定为字节数组,则应该没问题。如果要显示它,请使用BinToHex或IntToHex序列。
答案 3 :(得分: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;