By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,222 Members | 2,478 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,222 IT Pros & Developers. It's quick & easy.

Set parity of a string

P: n/a
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
Jul 18 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
snacktime wrote:
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
Jul 18 '05 #2

P: n/a
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.'
Jul 18 '05 #3

P: n/a

Peter Hansen wrote:
snacktime wrote:
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


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 ...

Jul 18 '05 #4

P: n/a
On Sun, 23 Jan 2005 21:00:25 -0500, Peter Hansen <pe***@engcorp.com> wrote:
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.


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
Jul 18 '05 #5

P: n/a
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

Jul 18 '05 #6

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

Chris
On Wed, 26 Jan 2005 11:50:46 -0800, snacktime <sn*******@gmail.com> wrote:
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).

Jul 18 '05 #7

P: n/a
snacktime wrote:
Correction on this, ETX is ok, it seems to be just STX with the data I am using. On Wed, 26 Jan 2005 11:50:46 -0800, snacktime <sn*******@gmail.com> wrote:
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).


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
Jul 18 '05 #8

P: n/a
Argh, never mind my mistake. I wasn't logging the data correctly the
parity conversion works fine.

Chris
Jul 18 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.