xor encryption: setting value of key to 904932 eating up 'd'
i am making a program to implement xor encryption,while playing around with my program i entered various key combinations the program was working perfectly until i entered value of key : 904932 which caused ommition of 'd' character e.g if i enter 'hi my name is dexter and i hate my stupid sister dede' in edit1,encrypting and decrypting back will make my edit1 text :'hi my name is exter an i hate my stupi sister开发者_运维问答 ee' what is going on?
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;
Adding 128 won't solve your problem. It just moves it.
Your "xor key" just xor the last byte of your key, that is $E4 in your case of 904932. $E4+128 will be rounded (i.e. -256) to byte value 100, which is the ASCII value of "d". That's why your "d" disappeared.
So I guess should NOT use such a xor algorithm if you want to display the encrypted text. I'd suggest that you make some simple permutation algorithm.
I actually recommend using modern cryptography like AES-CBC, but if you want to play with retro cryptography then lets have some fun here. Since your encryption output is text I might suggest the use of addition modulo rather than XOR. Only use XOR when working with bytes, not for characters. You'll need to avoid certain special characters in the output. In this case you appear to be having trouble with the NULL character. You could avoid output of characters by defining a character-set.
For example you might want to only use characters in the range of ASCII values 1 to 127 (all ASCII characters except NULL). That would mean that the base would be 1 and the modulus would be 126 = (127 - 1)
To encode a character, first subtract the base. Add the key value. Then, get the modulus result. Finally, add the base back in.
The decimal value of the lower case letter d is 100.
100 - 1 = 99 // subtract the base
99 + 904932 = 905031 // add the key value, used yours here
905031 % 126 = 99 // modulus result lol 904932 % 126 = 0
99 + 1 = 100 // add the base back in
Since your key value is divisible by the modulus 126 the output equals the input.
Undoing the addition modulo is a slightly different procedure.
100 - 1 = 99 // subtract the base
99 - 904932 = -904833 // subtract the key value
-904833 % 126 = -27 // modulus result
126 + -27 = 99 // add the modulus to the modulus result
99 + 1 = 100 // add the base back in
You can set the modulus as high as you want to include as many characters as you want into your character-set, and with some fancy math you can map characters to the integer values in any way.
While I do say that you can map the characters in any way you want the truth is that you're limited by the media that the text is written to. You can't set the modulus to be any higher than the total count of all characters that the media can carry, but you can have separate character mappings for encoded and decoded values.
I'll also comment on your key value selection. Applying the same key value to all characters is about the weakest possible form of encryption. (Can ROT13 really be considered encryption?) Think up some ways to vary the key value for each character. Somethings that were done when this type of crypto was in use was to increment the key by some value for each character, or to add the value of processed character to the key.
It is no problem to use XOR even if the resulting char is #0, because $00 xor $E4 = $E4
which reveals the original character. The problem is that you use the crypted result as a string which handles #0 specially. If you specify the crypted string as array of bytes you should be fine. If you want to display it use BinToHex or a sequence of IntToHex.
Here's a revision for you.
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;
精彩评论