0

I need a functionality to xor all possible single bytes with a bytestream. I have that function:

def byteChallenge(text):
    for i in range(0xff):
        res = ([bytes([i]) ^  bytes([a])  for a in text])
        print(res)

where text = bytes.fromhex(hexstring)

and I am getting an unreasonable error:

TypeError: unsupported operand type(s) for ^: 'bytes' and 'bytes'

both bytes[i] and bytes[a] are of the same bytes type. How i fix that?

aaossa
  • 3,763
  • 2
  • 21
  • 34
curious
  • 1,524
  • 6
  • 21
  • 45
  • Related: [Convert bytes to int?](https://stackoverflow.com/q/34009653/11082165) – Brian61354270 Mar 02 '22 at 14:36
  • it shouldn't be the only solution to convert it to integers. Why xor cannot operate directly on bytes? – curious Mar 02 '22 at 14:42
  • 2
    What would `b'\01\02' ^ b'\01'` be? An`int` already has an implied padding (0s on the left) for XORing two values. No such implicit padding exists for bytes, so `bytes` doesn't try to pick one. It just doesn't support `^` at all, and lets the user decide on an appropriate conversion to `int`. – chepner Mar 02 '22 at 14:43
  • why that works then: `bytes([_x ^ _y for _x, _y in zip(a, b)])` where a,b are similarly bytes fetched from `bytes.fromhex` ? – curious Mar 02 '22 at 14:46
  • 2
    Because `_x` and `_y` are `int` values. A `bytes` iterator produces integers, not single-byte `bytes` values. – chepner Mar 02 '22 at 14:47
  • 2
    `list(b'\01\02\03') == [1,2,3]`, not `[b'\x01', b'\x02, b'\x03']`. – chepner Mar 02 '22 at 14:48
  • 1
    By the way, `range(0xff)` won't give you every possible byte value, for that you need `range(0x100)` because a range never includes its endpoint. – Mark Ransom Mar 03 '22 at 01:16

1 Answers1

2

You can XOR arbitrary int value because, as arbitrary precision values, any pair of int values can be thought of as bit sequences of identical length, with high-order 0s padded as necessary to the smaller of the two value.

bytes, though, just represent sequences of bytes with no semantics about what those bytes mean. If the two values were of equal length, you could compute the XOR of pairwise elements. But if the value are of different lengths, what should the result be? You could pad the shorter sequence, but with what byte(s)? And should the padding be higher- or lower-order bytes in the sequence?

There's no obvious answer, so bytes doesn't try to impose one. It simply doesn't support XOR, leaving it to the user to interpret the bytes in a way that XOR makes sense.

chepner
  • 497,756
  • 71
  • 530
  • 681