Set parity of a string

snacktime snacktime at gmail.com
Wed Jan 26 20:50:46 CET 2005


I'm trying to figure out why the following code transforms ascii STX
(control-b) into "\x82".  The perl module I use returns a value of
"^B", and that is also what the application I am communicating with
expects to see.  Some ascii characters such as FS and GS come through
fine, but STX and ETX get transformed incorrectly (at least for what I
need they do).

What am I missing here?

Chris

> 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.'
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list