views:

169

answers:

4

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;
+1  A: 

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.

Uwe Raabe
+5  A: 

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.

A.Bouchez
the point being that an integer is 4 bytes while the character in this case obviously is a single byte. So OP must be using a version pre-D2009. D2009+ would have used two bytes for the character and wouldn't have shown the problem, or it would have manifested itself in another way.
Marjan Venema
D2009+ version would have shown the same problem, just with a rounding offset of 65536 instead of 256, because the key is a 32 bit integer. So the key number would be another one, but easy to guess, for example 65508 would have deleted the same 'd' characters, since 65508=65536-128+100.
A.Bouchez
thanks for answering my question,i still have some confusions: ''Your "xor key" just xor the last byte of your key'' why does xor key only xor's the last byte of key what is the reason and how to overcome it(if possible) ''So I guess should NOT use such a xor algorithm if you want to display the encrypted text'' then why is internet full of xor encryption examples?
Omair Iqbal
The reason of the byte range used, is the way you coded it: c := char(ord(c) xor key); which will work with char, i.e. a Byte (or a Word under Delphi 2009/2010/XE) range.If you use a xor, you'll get a lot of non printable characters (for example, below ASCII code 32). And even you could get the #0. Xor is the basic for encryption, but for storage purposes. For display purpose, use rather character permutations or other encoding schemes (like Bin64 or such).
A.Bouchez
character permutations vs encoding schemes whch one is better and which one is easier(i am a noob)
Omair Iqbal
+1  A: 

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; 
Ken Bourassa
It won't work as expected, for example if the character ASCII code matchs the key value (byte-converted), it will store #0. Which is a problem.
A.Bouchez
It probably won't display properly, yeah. But it should work as expected if "S" is manipulated correctly. But then again, we encrypt string for storage purpose, not for display. Of course, if the purpose is display, there are very few encryption algorythm that will do unless you convert, for exemple, in Base64. But then, XOR encryption becomes totally valid.
Ken Bourassa
+2  A: 

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.

Lunatic Experimentalist
seems interesting thanks
Omair Iqbal