Set parity of a string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • snacktime

    #1

    Set parity of a string

    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
  • Peter Hansen

    #2
    Re: Set parity of a string

    snacktime wrote:[color=blue]
    > 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.[/color]

    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.translat e for
    each string.

    -Peter

    Comment

    • Peter Hansen

      #3
      Re: Set parity of a string

      Peter Hansen wrote:[color=blue]
      > snacktime wrote:[color=green]
      >> Is there a module that sets the parity of a string?[/color]
      >
      > As to the specific question: a module is not really required.[/color]

      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(pari ty):
      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(pari ty, [0,0])[even_odd])
      table.append(cp )
      table.extend(ch r(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(pari ty)


      def set_parity(data , parity='none'):
      '''return string with parity bits, accepting only ASCII characters
      (0..127) as input'''
      out = string.translat e(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(inpu t)
      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\x f4'),
      ('Odd', '\x00test\x7f', '\x80\xf4\xe5s\ xf4\x7f'),
      ('even', '\x00\x01\x02\x 03test\x7d\x7e\ x7f',
      '\x00\x81\x82\x 03te\xf3t\x7d\x 7e\xff'),
      ]):
      actual = set_parity(inpu t, parity)
      assert expected == actual, 'case %d: %r != %r' % (i, expected, actual)

      print 'All tests passed.'

      Comment

      • John Machin

        #4
        Re: Set parity of a string


        Peter Hansen wrote:[color=blue]
        > snacktime wrote:[color=green]
        > > 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[/color][/color]
        [color=blue][color=green]
        > > So what I need is before sending the message, convert it from space[/color][/color]
        to[color=blue][color=green]
        > > even parity. And when I get the response I need to convert that[/color][/color]
        from[color=blue][color=green]
        > > even to space parity.[/color]
        >
        > By what means are the messages being delivered? I've rarely
        > seen parity used outside of simple RS-232-style serial[/color]
        communications.[color=blue]
        > 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.translat e for
        > each string.
        >
        > -Peter[/color]

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

        Comment

        • snacktime

          #5
          Re: Set parity of a string

          On Sun, 23 Jan 2005 21:00:25 -0500, Peter Hansen <peter@engcorp. com> wrote:[color=blue]
          > Peter Hansen wrote:[color=green]
          > > snacktime wrote:[color=darkred]
          > >> Is there a module that sets the parity of a string?[/color]
          > >
          > > As to the specific question: a module is not really required.[/color]
          >
          > 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.[/color]

          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

          Comment

          • snacktime

            #6
            Re: Set parity of a string

            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
            [color=blue]
            > 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(pari ty):
            > 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(pari ty, [0,0])[even_odd])
            > table.append(cp )
            > table.extend(ch r(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(pari ty)
            >
            > def set_parity(data , parity='none'):
            > '''return string with parity bits, accepting only ASCII characters
            > (0..127) as input'''
            > out = string.translat e(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(inpu t)
            > 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\x f4'),
            > ('Odd', '\x00test\x7f', '\x80\xf4\xe5s\ xf4\x7f'),
            > ('even', '\x00\x01\x02\x 03test\x7d\x7e\ x7f',
            > '\x00\x81\x82\x 03te\xf3t\x7d\x 7e\xff'),
            > ]):
            > actual = set_parity(inpu t, parity)
            > assert expected == actual, 'case %d: %r != %r' % (i, expected, actual)
            >
            > print 'All tests passed.'
            > --
            > http://mail.python.org/mailman/listinfo/python-list
            >[/color]

            Comment

            • snacktime

              #7
              Re: Set parity of a string

              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 <snacktime@gmai l.com> wrote:[color=blue]
              > 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).[/color]

              Comment

              • Peter Hansen

                #8
                Re: Set parity of a string

                snacktime wrote:[color=blue]
                > Correction on this, ETX is ok, it seems to be just STX with the data I am using.[/color]
                [color=blue]
                > On Wed, 26 Jan 2005 11:50:46 -0800, snacktime <snacktime@gmai l.com> wrote:
                >[color=green]
                >>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).[/color][/color]

                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

                Comment

                • snacktime

                  #9
                  Re: Set parity of a string

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

                  Chris

                  Comment

                  Working...