py2 to 3 base64 issues
On 2019-08-09 19:21, Larry Martell wrote:
> On Fri, Aug 9, 2019 at 12:23 PM Chris Angelico <rosuav at gmail.com> wrote:
>> On Sat, Aug 10, 2019 at 2:09 AM Larry Martell <larry.martell at gmail.com> wrote:
>> > I have some python 2 code:
>> > def decode(key, string):
>> > decoded_chars = 
>> > string = base64.urlsafe_b64decode(string)
>> > for i in range(len(string)):
>> > key_c = key[i % len(key)]
>> > encoded_c = chr(abs(ord(string[i]) - ord(key_c) % 256))
>> > decoded_chars.append(encoded_c)
>> > decoded_string = "".join(decoded_chars)
>> > return decoded_string
>> > and if I call it like this in py2 it works as expected:
>> > s = 'V3NYVY95iImnnJWCmqphWFFzU1qvqsV6x83Mxa7HipZitZeMxbe709jJtbfW6Y6blQ=='
>> > key = '!@#$VERYsecRet)('
>> > decode(key, s)
>> > In py3 it fails with
>> > TypeError: ord() expected string of length 1, but int found
>> > I know that in py3 base64.urlsafe_b64decode is returning bytes not
>> > chars and that is what that is happening, and I thought the solution
>> > would be to decode it, but what codec would I use for this?
>> Should be safe to decode it as ASCII, since Base 64 uses strictly
>> ASCII characters. But since you're working with bytes, possibly all
>> you need to do is remove the ord calls, since ord(u"x") is the same as
>> b"x". You'll then need to change the join() at the end to be just
>> "decoded_string = bytes(decoded_chars)", or possibly that followed by
>> a decode-to-text, depending on how your data works.
> That doesn't work:
> -> encoded_c = chr(abs(string[i] - ord(key_c) % 256))
> (Pdb) n
> TypeError: "unsupported operand type(s) for -: 'str' and 'int'"
> (Pdb) string
> (Pdb) string[i]
> (Pdb) bytes(string[i])
> (Pdb) type(string[i])
> <type 'str'>
'string' is a 'str' (in Python 2 that would've been 'unicode'), so
string[i] is also a 'str' and you need 'ord':
encoded_c = chr(abs(ord(string[i]) - ord(key_c) % 256))