http://www.perlmonks.org?node_id=799624


in reply to strings to number and XOR

$msg = "this is a test messagez"; $key = "\x4f\xcb"; # or $key = pack "n", 0x4fcb; $xored = $msg ^ $key; print join(" ", split(//, $msg)), "\n"; print join(" ", unpack("(H2)*", $msg)), "\n"; print join(" ", unpack("(H2)*", $key)), "\n"; print join(" ", unpack("(H2)*", $xored)), "\n"; __END__ t h i s i s a t e s t m e s s a g e z 74 68 69 73 20 69 73 20 61 20 74 65 73 74 20 6d 65 73 73 61 67 65 7a 4f cb 3b a3 69 73 20 69 73 20 61 20 74 65 73 74 20 6d 65 73 73 61 67 65 7a

The easiest way to generate your key string for the entire message is probably something like

$key = "\x4f\xcb" x (length($msg)/2); or $key = pack("n", 0x4fcb) x (length($msg)/2);

That way you can directly XOR both strings without any further ado:

t h i s i s a t e s t m e s s a g e z 74 68 69 73 20 69 73 20 61 20 74 65 73 74 20 6d 65 73 73 61 67 65 7a + $msg 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb + $key 3b a3 26 b8 6f a2 3c eb 2e eb 3b ae 3c bf 6f a6 2a b8 3c aa 28 ae 7a + XOR result

___

 $xitem =  unpack("H*", $array[1]) ^ $key;

What this is doing is XORing the hex-string "7468" (i.e. 4 ASCII chars, hex 37 34 36 38) with the Perl internal representation of the number 0x4fcb ...

Replies are listed 'Best First'.
Re^2: strings to number and XOR
by Anonymous Monk on Oct 07, 2009 at 05:13 UTC
    Brilliant! Pouring over my books I just couldn't grasp it. You made it crystal clear! Thanks, Aaron
Re^2: strings to number and XOR
by alager (Acolyte) on Oct 07, 2009 at 17:52 UTC
    Last question, then I should be done. :)
    For the variable
    $key = "\x4f\xcb"; How can I increment it?
    I've tried directly with $key++, but that starts counting at 0, I would expect \x4f\xcc as the result.

    And I've tried unpacking it. Which starts incrementing with the first number (4 in this case) and loses the rest of the data. eg 4,5,6...
    I would like
    0x4fcb 0x4fcc 0x4fcd ect.

    Thanks,
    Aaron

    UPDATE: I've found part of the problem, perl doesn't like to add numbers that aren't "numbers", this works fine as long as my bytes are in the range of ASCII numbers, but fails for values above outside of 0x30-0x39.

      I've tried directly with $key++

      The problem with Perl's string-increment is that the string has to match the pattern /^[a-zA-Z]*[0-9]*\z/ for it to work...(see perlop).  So you'd have to increment the corresponding numeric value, e.g.

      $key = "\x4f\xcb"; for (1..10) { $key = pack('n',unpack('n',$key)+1); # ++ print unpack("H*", $key), "\n"; } __END__ 4fcc 4fcd 4fce 4fcf 4fd0 4fd1 4fd2 4fd3 4fd4 4fd5
Re^2: strings to number and XOR
by Anonymous Monk on Oct 07, 2009 at 16:57 UTC
    Okay one last item. Using:$key = "\x4f\xcb" x (length($msg)/2); how do I handle odd length messages? We can see in your example too, that the last character is not xored, 0x7a. I would like it to be xored with 0x4f, or the first part of the key. Thanks for your help. Aaron
      I think I solved this. I just added 1 more, since an extra byte or two in the key doesn't hurt anything.
      $key = "\x4f\xcb" x ((length($msg)/2)+1);
      Aaron
        an extra byte or two in the key doesn't hurt anything

        It's maybe worth trimming your XORed string to the original length, or else half of your key pattern might leak... (to anyone who makes an educated guess about the procedure)

        t h i s i s a t e s t m e s s a g e z 74 68 69 73 20 69 73 20 61 20 74 65 73 74 20 6d 65 73 73 61 67 65 7a 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f cb 4f c +b 3b a3 26 b8 6f a2 3c eb 2e eb 3b ae 3c bf 6f a6 2a b8 3c aa 28 ae 35 c +b ^ +^

        ... just in case you do want to keep it secret (I don't really know what you intent to use this for).

        (OTOH, if encryption was the idea, and security was of any relevance, I'd choose a different approach anyway :)