Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/google-endpoints/rsa/transform.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/google-endpoints/rsa/randnum.py ('k') | third_party/google-endpoints/rsa/util.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # https://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """Data transformation functions.
18
19 From bytes to a number, number to bytes, etc.
20 """
21
22 from __future__ import absolute_import
23
24 try:
25 # We'll use psyco if available on 32-bit architectures to speed up code.
26 # Using psyco (if available) cuts down the execution time on Python 2.5
27 # at least by half.
28 import psyco
29
30 psyco.full()
31 except ImportError:
32 pass
33
34 import binascii
35 from struct import pack
36 from rsa import common
37 from rsa._compat import is_integer, b, byte, get_word_alignment, ZERO_BYTE, EMPT Y_BYTE
38
39
40 def bytes2int(raw_bytes):
41 r"""Converts a list of bytes or an 8-bit string to an integer.
42
43 When using unicode strings, encode it to some encoding like UTF8 first.
44
45 >>> (((128 * 256) + 64) * 256) + 15
46 8405007
47 >>> bytes2int(b'\x80@\x0f')
48 8405007
49
50 """
51
52 return int(binascii.hexlify(raw_bytes), 16)
53
54
55 def _int2bytes(number, block_size=None):
56 r"""Converts a number to a string of bytes.
57
58 Usage::
59
60 >>> _int2bytes(123456789)
61 b'\x07[\xcd\x15'
62 >>> bytes2int(_int2bytes(123456789))
63 123456789
64
65 >>> _int2bytes(123456789, 6)
66 b'\x00\x00\x07[\xcd\x15'
67 >>> bytes2int(_int2bytes(123456789, 128))
68 123456789
69
70 >>> _int2bytes(123456789, 3)
71 Traceback (most recent call last):
72 ...
73 OverflowError: Needed 4 bytes for number, but block size is 3
74
75 @param number: the number to convert
76 @param block_size: the number of bytes to output. If the number encoded to
77 bytes is less than this, the block will be zero-padded. When not given,
78 the returned block is not padded.
79
80 @throws OverflowError when block_size is given and the number takes up more
81 bytes than fit into the block.
82 """
83
84 # Type checking
85 if not is_integer(number):
86 raise TypeError("You must pass an integer for 'number', not %s" %
87 number.__class__)
88
89 if number < 0:
90 raise ValueError('Negative numbers cannot be used: %i' % number)
91
92 # Do some bounds checking
93 if number == 0:
94 needed_bytes = 1
95 raw_bytes = [ZERO_BYTE]
96 else:
97 needed_bytes = common.byte_size(number)
98 raw_bytes = []
99
100 # You cannot compare None > 0 in Python 3x. It will fail with a TypeError.
101 if block_size and block_size > 0:
102 if needed_bytes > block_size:
103 raise OverflowError('Needed %i bytes for number, but block size '
104 'is %i' % (needed_bytes, block_size))
105
106 # Convert the number to bytes.
107 while number > 0:
108 raw_bytes.insert(0, byte(number & 0xFF))
109 number >>= 8
110
111 # Pad with zeroes to fill the block
112 if block_size and block_size > 0:
113 padding = (block_size - needed_bytes) * ZERO_BYTE
114 else:
115 padding = EMPTY_BYTE
116
117 return padding + EMPTY_BYTE.join(raw_bytes)
118
119
120 def bytes_leading(raw_bytes, needle=ZERO_BYTE):
121 """
122 Finds the number of prefixed byte occurrences in the haystack.
123
124 Useful when you want to deal with padding.
125
126 :param raw_bytes:
127 Raw bytes.
128 :param needle:
129 The byte to count. Default \000.
130 :returns:
131 The number of leading needle bytes.
132 """
133
134 leading = 0
135 # Indexing keeps compatibility between Python 2.x and Python 3.x
136 _byte = needle[0]
137 for x in raw_bytes:
138 if x == _byte:
139 leading += 1
140 else:
141 break
142 return leading
143
144
145 def int2bytes(number, fill_size=None, chunk_size=None, overflow=False):
146 """
147 Convert an unsigned integer to bytes (base-256 representation)::
148
149 Does not preserve leading zeros if you don't specify a chunk size or
150 fill size.
151
152 .. NOTE:
153 You must not specify both fill_size and chunk_size. Only one
154 of them is allowed.
155
156 :param number:
157 Integer value
158 :param fill_size:
159 If the optional fill size is given the length of the resulting
160 byte string is expected to be the fill size and will be padded
161 with prefix zero bytes to satisfy that length.
162 :param chunk_size:
163 If optional chunk size is given and greater than zero, pad the front of
164 the byte string with binary zeros so that the length is a multiple of
165 ``chunk_size``.
166 :param overflow:
167 ``False`` (default). If this is ``True``, no ``OverflowError``
168 will be raised when the fill_size is shorter than the length
169 of the generated byte sequence. Instead the byte sequence will
170 be returned as is.
171 :returns:
172 Raw bytes (base-256 representation).
173 :raises:
174 ``OverflowError`` when fill_size is given and the number takes up more
175 bytes than fit into the block. This requires the ``overflow``
176 argument to this function to be set to ``False`` otherwise, no
177 error will be raised.
178 """
179
180 if number < 0:
181 raise ValueError("Number must be an unsigned integer: %d" % number)
182
183 if fill_size and chunk_size:
184 raise ValueError("You can either fill or pad chunks, but not both")
185
186 # Ensure these are integers.
187 number & 1
188
189 raw_bytes = b('')
190
191 # Pack the integer one machine word at a time into bytes.
192 num = number
193 word_bits, _, max_uint, pack_type = get_word_alignment(num)
194 pack_format = ">%s" % pack_type
195 while num > 0:
196 raw_bytes = pack(pack_format, num & max_uint) + raw_bytes
197 num >>= word_bits
198 # Obtain the index of the first non-zero byte.
199 zero_leading = bytes_leading(raw_bytes)
200 if number == 0:
201 raw_bytes = ZERO_BYTE
202 # De-padding.
203 raw_bytes = raw_bytes[zero_leading:]
204
205 length = len(raw_bytes)
206 if fill_size and fill_size > 0:
207 if not overflow and length > fill_size:
208 raise OverflowError(
209 "Need %d bytes for number, but fill size is %d" %
210 (length, fill_size)
211 )
212 raw_bytes = raw_bytes.rjust(fill_size, ZERO_BYTE)
213 elif chunk_size and chunk_size > 0:
214 remainder = length % chunk_size
215 if remainder:
216 padding_size = chunk_size - remainder
217 raw_bytes = raw_bytes.rjust(length + padding_size, ZERO_BYTE)
218 return raw_bytes
219
220
221 if __name__ == '__main__':
222 import doctest
223
224 doctest.testmod()
OLDNEW
« no previous file with comments | « third_party/google-endpoints/rsa/randnum.py ('k') | third_party/google-endpoints/rsa/util.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698