Set parity of a string

Peter Hansen peter at engcorp.com
Sun Jan 23 21:00:25 EST 2005


Peter Hansen wrote:
> snacktime wrote:
>> Is there a module that sets the parity of a string?  
> 
> As to the specific question: a module is not really required.

But here's one for you anyway.  It raises an exception if any
input character is non-ASCII, otherwise when you call set_parity()
with a string and a parity parameter of 'even', 'mark', 'none',
'odd', or 'space', it returns a string of the same length with
the high (parity) bits set appropriately.

'''parity module for python'''
# Copyright 2005 Engenuity Corporation
# Released under the "MIT license"
# at http://www.opensource.org/licenses/mit-license.php


import string
import operator


def _makeTable(parity):
     bitMap = {'even': [0,128], 'odd': [128,0], 'mark': [128,128]}
     table = []
     for c in range(128):
         even_odd = (sum(bool(c & 1<<b) for b in range(8))) & 1
         cp = chr(c | bitMap.get(parity, [0,0])[even_odd])
         table.append(cp)
     table.extend(chr(c) for c in range(128, 256))
     table = ''.join(table)
     return table, table[128:]


_map = {}
for parity in 'even odd mark space none'.split():
     _map[parity] = _makeTable(parity)


def set_parity(data, parity='none'):
     '''return string with parity bits, accepting only ASCII characters 
(0..127) as input'''
     out = string.translate(data, *_map[parity.lower()])
     if len(out) != len(data):
         raise ValueError('non-ASCII characters in input')
     else:
         return out


if __name__ == '__main__':
     print 'Running self-tests for parity.py'

     # check for invalid input handling
     for input in [ '\xff', '\x80', 'test\xA0ing' ]:
         try:
             set_parity(input)
         except ValueError:
             pass
         else:
             assert False, 'no exception for non-ASCII input'

     # check for various valid inputs
     for i, (parity, input, expected) in enumerate([
         ('space', 'test', 'test'),
         ('SPACE', '\x00\x7f', '\x00\x7f'),
         ('mark', 'test', '\xf4\xe5\xf3\xf4'),
         ('Odd', '\x00test\x7f', '\x80\xf4\xe5s\xf4\x7f'),
         ('even', '\x00\x01\x02\x03test\x7d\x7e\x7f', 
'\x00\x81\x82\x03te\xf3t\x7d\x7e\xff'),
         ]):
         actual = set_parity(input, parity)
         assert expected == actual, 'case %d: %r != %r' % (i, expected, actual)

     print 'All tests passed.'



More information about the Python-list mailing list