99def bit_size (number ):
1010 """Returns the number of bits required to hold a specific long number"""
1111
12+ if number < 0 :
13+ raise ValueError ('Only nonnegative numbers possible: %s' % number )
14+
15+ if number == 0 :
16+ return 1
17+
1218 return int (math .ceil (math .log (number , 2 )))
1319
20+ def byte_size (number ):
21+ """Returns the number of bytes required to hold a specific long number.
22+
23+ The number of bytes is rounded up.
24+ """
25+
26+ return int (math .ceil (bit_size (number ) / 8.0 ))
27+
1428def bytes2int (bytes ):
1529 """Converts a list of bytes or an 8-bit string to an integer.
1630
@@ -72,7 +86,7 @@ def int2bytes(number, block_size=None):
7286
7387 # Do some bounds checking
7488 if block_size is not None :
75- needed_bytes = int ( math . ceil ( bit_size ( number ) / 8.0 ) )
89+ needed_bytes = byte_size ( number )
7690 if needed_bytes > block_size :
7791 raise OverflowError ('Needed %i bytes for number, but block size '
7892 'is %i' % (needed_bytes , block_size ))
@@ -92,6 +106,31 @@ def int2bytes(number, block_size=None):
92106 return padding + '' .join (bytes )
93107
94108
109+ def block_op (block_provider , block_size , operation ):
110+ r'''Generator, applies the operation on each block and yields the result
111+
112+ Each block is converted to a number, the given operation is applied and then
113+ the resulting number is converted back to a block of data. The resulting
114+ block is yielded.
115+
116+ @param block_provider: an iterable that iterates over the data blocks.
117+ @param block_size: the used block size
118+ @param operation: a function that accepts an integer and returns an integer
119+
120+ >>> blocks = ['\x00\x01\x02', '\x03\x04\x05']
121+ >>> list(block_op(blocks, 3, lambda x: (x + 6)))
122+ ['\x00\x01\x08', '\x03\x04\x0b']
123+
124+ '''
125+
126+ for block in block_provider :
127+ number = bytes2int (block )
128+ print 'In : %i (%i bytes)' % (number , byte_size (number ))
129+ after_op = operation (number )
130+ print 'Out: %i (%i bytes)' % (after_op , byte_size (after_op ))
131+ yield int2bytes (after_op , block_size )
132+
133+
95134def to64 (number ):
96135 """Converts a number in the range of 0 to 63 into base 64 digit
97136 character in the range of '0'-'9', 'A'-'Z', 'a'-'z','-','_'.
0 commit comments