The tricky part of the functions you show is that they encode the amount of padding being applied in the ASCII value of the padding character using chr
and ord
to encode and decode the value, respectively. That's pretty clever. It does require that all strings be padded though, even ones who's lengths were already exact multiples of self.bs
.
Here's a clearer version of the two functions, which has the different steps explicitly split out:
def _pad(self, s):
amount_of_padding = self.bs - len(s) % self.bs # between 1 and self.bs, inclusive
padding_char = chr(amount_of_padding) # encode amount_of_padding in ASCII!
return s + amount_of_padding * padding_char # do string repetition with *
def _unpad(self, s):
padding_char = s[-1] # last char is always part of the padding
amount_of_padding = ord(padding_char) # decode amount from ASCII value of char
return s[:-amount_of_padding] # slice to skip padding chars
The only odd thing in the original code is in _unpad
where they use of s[len(s)-1]
rather than s[-1]
. I don't see any reason for that, since the two expressions do exactly the same thing (get the last character).