title: Understanding Python struct.pack and binary input
body: <p>The following function accepts a binary 4 byte key for <code>key</code>. <code>buf</code> is binary input which is xor'd against the 4 byte key.</p>
  
  <pre><code>def four_byte_xor(buf, key):
      #key = struct.pack(b"&gt;I", key) # removed for binary processing
      buf = bytearray(buf)
      for offset in range(0, len(buf), 4):
          for i, byte in enumerate(key):
              buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
      return str(buf)
  </code></pre>
  
  <p>I removed <code>key = struct.pack(b"&gt;I", key)</code> from <code>four_byte_xor()</code> in order to specify binary data via <code>str(p.payload.payload.payload)[:4]</code> for <code>key</code>. This works fine if the length end in 4 bytes, otherwise the following error fires (see testing below).</p>
  
  <p>Here are some tests consisting of an input xor'd with a key resulting in 00, first one being successful:</p>
  
  <pre><code>'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD'
  'ABCD'
  
  bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
  'ABCD'
  </code></pre>
  
  <p>Second test is not successful and end in A or 1 extra byte:</p>
  
  <pre><code>'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA'
  'ABCD'
  Traceback (most recent call last):
    File "./decode.py", line 36, in &lt;module&gt;
      process_packets()
    File "./decode.py", line 34, in process_packets
      out_buf.write(bin_four_byte_xor(pkt_payload, pkt_offset))
    File "./decode.py", line 22, in bin_four_byte_xor
      buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
  IndexError: bytearray index out of range
  </code></pre>
  
  <p>Can the <code>four_byte_xor()</code> be modified to accept varying <code>buf</code> lengths?</p>