Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(34642)

Side by Side Diff: Lib/base64.py

Issue 17839: base64 module should use memoryview
Patch Set: Created 6 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #! /usr/bin/env python3 1 #! /usr/bin/env python3
2 2
3 """RFC 3548: Base16, Base32, Base64 Data Encodings""" 3 """RFC 3548: Base16, Base32, Base64 Data Encodings"""
4 4
5 # Modified 04-Oct-1995 by Jack Jansen to use binascii module 5 # Modified 04-Oct-1995 by Jack Jansen to use binascii module
6 # Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support 6 # Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support
7 # Modified 22-May-2007 by Guido van Rossum to use bytes everywhere 7 # Modified 22-May-2007 by Guido van Rossum to use bytes everywhere
8 8
9 import re 9 import re
10 import struct 10 import struct
(...skipping 17 matching lines...) Expand all
28 28
29 29
30 bytes_types = (bytes, bytearray) # Types acceptable as binary data 30 bytes_types = (bytes, bytearray) # Types acceptable as binary data
31 31
32 def _bytes_from_decode_data(s): 32 def _bytes_from_decode_data(s):
33 if isinstance(s, str): 33 if isinstance(s, str):
34 try: 34 try:
35 return s.encode('ascii') 35 return s.encode('ascii')
36 except UnicodeEncodeError: 36 except UnicodeEncodeError:
37 raise ValueError('string argument should contain only ASCII characte rs') 37 raise ValueError('string argument should contain only ASCII characte rs')
38 elif isinstance(s, bytes_types): 38 if isinstance(s, bytes_types):
39 return s 39 return s
40 else: 40 try:
41 raise TypeError("argument should be bytes or ASCII string, not %s" % s._ _class__.__name__) 41 return memoryview(s).tobytes()
Nick Coghlan 2013/05/19 13:22:58 While I don't believe the current incarnation of t
42 42 except TypeError:
43 raise TypeError("argument should be bytes-like object or ASCII string, "
ezio.melotti 2013/05/07 09:38:03 should be a bytes-like object
44 "not %s" % s.__class__.__name__) from None
43 45
44 46
45 # Base64 encoding/decoding uses binascii 47 # Base64 encoding/decoding uses binascii
46 48
47 def b64encode(s, altchars=None): 49 def b64encode(s, altchars=None):
48 """Encode a byte string using Base64. 50 """Encode a byte string using Base64.
49 51
50 s is the byte string to encode. Optional altchars must be a byte 52 s is the byte string to encode. Optional altchars must be a byte
51 string of length 2 which specifies an alternative alphabet for the 53 string of length 2 which specifies an alternative alphabet for the
52 '+' and '/' characters. This allows an application to 54 '+' and '/' characters. This allows an application to
53 e.g. generate url or filesystem safe Base64 strings. 55 e.g. generate url or filesystem safe Base64 strings.
54 56
55 The encoded byte string is returned. 57 The encoded byte string is returned.
56 """ 58 """
57 if not isinstance(s, bytes_types):
58 raise TypeError("expected bytes, not %s" % s.__class__.__name__)
59 # Strip off the trailing newline 59 # Strip off the trailing newline
60 encoded = binascii.b2a_base64(s)[:-1] 60 encoded = binascii.b2a_base64(s)[:-1]
61 if altchars is not None: 61 if altchars is not None:
62 if not isinstance(altchars, bytes_types):
63 raise TypeError("expected bytes, not %s"
64 % altchars.__class__.__name__)
65 assert len(altchars) == 2, repr(altchars) 62 assert len(altchars) == 2, repr(altchars)
66 return encoded.translate(bytes.maketrans(b'+/', altchars)) 63 return encoded.translate(bytes.maketrans(b'+/', altchars))
67 return encoded 64 return encoded
68 65
69 66
70 def b64decode(s, altchars=None, validate=False): 67 def b64decode(s, altchars=None, validate=False):
71 """Decode a Base64 encoded byte string. 68 """Decode a Base64 encoded byte string.
72 69
73 s is the byte string to decode. Optional altchars must be a 70 s is the byte string to decode. Optional altchars must be a
74 string of length 2 which specifies the alternative alphabet used 71 string of length 2 which specifies the alternative alphabet used
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 _b32tab = [v[0] for k, v in sorted(_b32alphabet.items())] 150 _b32tab = [v[0] for k, v in sorted(_b32alphabet.items())]
154 _b32rev = dict([(v[0], k) for k, v in _b32alphabet.items()]) 151 _b32rev = dict([(v[0], k) for k, v in _b32alphabet.items()])
155 152
156 153
157 def b32encode(s): 154 def b32encode(s):
158 """Encode a byte string using Base32. 155 """Encode a byte string using Base32.
159 156
160 s is the byte string to encode. The encoded byte string is returned. 157 s is the byte string to encode. The encoded byte string is returned.
161 """ 158 """
162 if not isinstance(s, bytes_types): 159 if not isinstance(s, bytes_types):
163 raise TypeError("expected bytes, not %s" % s.__class__.__name__) 160 try:
161 s = memoryview(s).tobytes()
Nick Coghlan 2013/05/19 13:22:58 Same comment as above - doing the tobytes() call i
162 except TypeError:
163 raise TypeError("expected bytes-like object, not %s" %
ezio.melotti 2013/05/07 09:38:03 This (and the previous one) could be %r instead of
164 s.__class__.__name__) from None
164 quanta, leftover = divmod(len(s), 5) 165 quanta, leftover = divmod(len(s), 5)
165 # Pad the last quantum with zero bits if necessary 166 # Pad the last quantum with zero bits if necessary
166 if leftover: 167 if leftover:
167 s = s + bytes(5 - leftover) # Don't use += ! 168 s = s + bytes(5 - leftover) # Don't use += !
168 quanta += 1 169 quanta += 1
169 encoded = bytes() 170 encoded = bytes()
170 for i in range(quanta): 171 for i in range(quanta):
171 # c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this 172 # c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this
172 # code is to process the 40 bits in units of 5 bits. So we take the 1 173 # code is to process the 40 bits in units of 5 bits. So we take the 1
173 # leftover bit of c1 and tack it onto c2. Then we take the 2 leftover 174 # leftover bit of c1 and tack it onto c2. Then we take the 2 leftover
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 273
273 274
274 # RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns 275 # RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
275 # lowercase. The RFC also recommends against accepting input case 276 # lowercase. The RFC also recommends against accepting input case
276 # insensitively. 277 # insensitively.
277 def b16encode(s): 278 def b16encode(s):
278 """Encode a byte string using Base16. 279 """Encode a byte string using Base16.
279 280
280 s is the byte string to encode. The encoded byte string is returned. 281 s is the byte string to encode. The encoded byte string is returned.
281 """ 282 """
282 if not isinstance(s, bytes_types):
283 raise TypeError("expected bytes, not %s" % s.__class__.__name__)
284 return binascii.hexlify(s).upper() 283 return binascii.hexlify(s).upper()
285 284
286 285
287 def b16decode(s, casefold=False): 286 def b16decode(s, casefold=False):
288 """Decode a Base16 encoded byte string. 287 """Decode a Base16 encoded byte string.
289 288
290 s is the byte string to decode. Optional casefold is a flag 289 s is the byte string to decode. Optional casefold is a flag
291 specifying whether a lowercase alphabet is acceptable as input. 290 specifying whether a lowercase alphabet is acceptable as input.
292 For security purposes, the default is False. 291 For security purposes, the default is False.
293 292
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 print(repr(s0)) 400 print(repr(s0))
402 s1 = encodebytes(s0) 401 s1 = encodebytes(s0)
403 print(repr(s1)) 402 print(repr(s1))
404 s2 = decodebytes(s1) 403 s2 = decodebytes(s1)
405 print(repr(s2)) 404 print(repr(s2))
406 assert s0 == s2 405 assert s0 == s2
407 406
408 407
409 if __name__ == '__main__': 408 if __name__ == '__main__':
410 main() 409 main()
OLDNEW

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+