Set parity of a string

S

snacktime

Is there a module that sets the parity of a string? I have an
application that needs to communicate with a host using even parity
So what I need is before sending the message, convert it from space to
even parity. And when I get the response I need to convert that from
even to space parity.

The perl module String::parity is what I have used to do this under perl.

Chris
 
P

Peter Hansen

snacktime said:
Is there a module that sets the parity of a string? I have an
application that needs to communicate with a host using even parity
So what I need is before sending the message, convert it from space to
even parity. And when I get the response I need to convert that from
even to space parity.

By what means are the messages being delivered? I've rarely
seen parity used outside of simple RS-232-style serial communications.
Certainly not (in my experience, though it's doubtless been done)
in TCP/IP based stuff. And if it's serial, parity can be
supplied at a lower level than your code.

As to the specific question: a module is not really required.
The parity value of a character depends only on the binary
value of that one byte, so a simple 128-byte substitution
table is all you need, plus a call to string.translate for
each string.

-Peter
 
P

Peter Hansen

Peter said:
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.'
 
J

John Machin

Peter said:
By what means are the messages being delivered? I've rarely
seen parity used outside of simple RS-232-style serial communications.
Certainly not (in my experience, though it's doubtless been done)
in TCP/IP based stuff. And if it's serial, parity can be
supplied at a lower level than your code.

As to the specific question: a module is not really required.
The parity value of a character depends only on the binary
value of that one byte, so a simple 128-byte substitution
table is all you need, plus a call to string.translate for
each string.

-Peter

And for converting back from even parity to space parity, either a
256-byte translation table, or a bit of bit bashing, like chr(ord(c) &
127), on each byte.

The bank story sounds eminently plausible to me. Pick up old system
where branch manager had to dial HO every evening, insert phone into
acoustic coupler, etc etc and dump it on the internet ...
 
S

snacktime

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.

Thanks for the code example, I'm not quite up to speed on python
enough to make this a trivial exercise as of yet.

Chris
 
S

snacktime

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
 
S

snacktime

Correction on this, ETX is ok, it seems to be just STX with the data I am using.

Chris
 
S

snacktime

Argh, never mind my mistake. I wasn't logging the data correctly the
parity conversion works fine.

Chris
 
P

Peter Hansen

snacktime said:
Correction on this, ETX is ok, it seems to be just STX with the data I am using.

I didn't see the first post, which you quoted above... more newsfeed
or python-list misalignment I guess. :-(

Anyway, since STX '\x02' has only one bit set, if you are setting
the parity bit for "even" parity, then naturally it will be set
(in order to make the total number of "on" bits an even number),
so you get '\x82' (which has two bits set). ETX, on the other
hand '\x03' already has two bits set, so the high bit is left alone.

It sounds as though you need to examine the specification
for the receiving system in more detail, or perhaps seek
clarification from the other party involved in this system
you're working with. If you have examples that show STX and
ETX both being transmitted, around other data which itself
has had the parity bit set for even parity, then clearly (a)
the folks involved in designing that system are idiots
<0.5 wink> and (b) you'll have to modify the way you are
forming the transmission packet. It appears they may want
the STX/ETX pair to be sent without being affected by the
parity process...

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top