The best way of calculating and adding a block check character to a string

H J van Rooyen mail at microcorp.co.za
Sun May 14 19:28:31 CEST 2006


Hi All

I am new to this language, and in using it to drive a serial port, I need to calculate classic block check characters - for the veterans amongst you - think "Burroughs Poll Select" or "Uniscope"...

This is a program fragment that puts the string in an array of Bytes - is there a better way to do this job?  - the annotated action starts after the ascii definitions of the first 32 control characters...

# some ascii control character values defined

nul = '\x00' # null char

soh = '\x01' # start of header

stx = '\x02' # start of text

etx = '\x03' # end of text

eot = '\x04' # end of transmission

enq = '\x05' # enquiry

ack = '\x06' # ack

bel = '\x07' # bell char

bs = '\x08' # backspace

ht = '\x09' # horizontal tab

lf = '\x0a' # line feed - linux newline

vt = '\x0b' # vertical tab

ff = '\x0c' # form feed

cr = '\x0d' # carriage return

so = '\x0e' # shift out

si = '\x0f' # shift in

dle = '\x10' # data link escape

dc1 = '\x11' # data control 1 - aka xon

dc2 = '\x12' # data control 2 

dc3 = '\x13' # data control 3 - aka xoff

dc4 = '\x14' # data control 4

nak = '\x15' # negative acknowledgement

syn = '\x16' # sync char

etb = '\x17' # end of transmission block

can = '\x18' # cancel

em = '\x19' # end of message

sub = '\x1a' # sub

esc = '\x1b' # escape

fs = '\x1c' # field separator

gs = '\x1d' # group separator

rs = '\x1e' # record separator

us = '\x1f' # unit separator



# some strings defined


poll = soh + 'P' + 'A' + stx + etx # rudimentary poll string 

bcc = nul

# here starts the trouble:


ar = array.array('B', poll)


bccint = ar[0] # this is prolly dicey - what type and how big is this?


for x in ar[1:]:

    bccint = bccint ^ x # this works, but is it the best way?


print repr(bccint)


ar.append(bccint)


# this seems so left-handed - we make a string, then we put it in an array,

# then we iterate over the array elements to calculate the

# bcc (block check character), then we add it to the array - then we should

# really make it all a string again to write it to the port...

# it would be nice to be able to write:

# nul = '\x00'

# bcc = nul

# poll = "some arbitrary string"

# bcc = bcc ^ (x for x in poll[0:]) # calculate and

# poll = poll + bcc # add the bcc to the string

# port.write(poll) # and write the lot to the port

# port.flush()

# and on the way in:

# numchars = 5 # some magic number depending on what we are expecting back

# response = port.read(numchars) # or a more complicated char at a time function

# bcc = nul

# bcc = bcc ^ (x for x in response[0:])

# if bcc != nul:

#     error_routine(response)

# so we would stay working with strings - the stuff from the port

# coming in is a string, and we need a string to write again...

# *grin* but of course the xor and strong typing won't allow the

# string - to say nothing of the iterator...



# here is a loop, demonstrating getting an arbitrary lf terminated string in,

# and writing the fixed one with a bcc tagged on out as a response, along

# with some debug printing.

s = esc + '@' + esc + 'v' + lf # the line we are searching for


while True:

    try:

        buffer = port.readline() # read in as a string, (unblocked)

    except KeyboardInterrupt:

        print "\n^C - Returning to Shell - Error is:", KeyboardInterrupt

        ret_val = 1 # ^C while waiting for input

        return buffer, ret_val # go out on error

    except IOError:

        continue # IOError on input - no record available

    if buffer == '': # empty string is rubbish - ignore it

        continue

    rawfile.write(buffer) # Keep the record as read

    print repr(buffer) # show how python sees it

    print repr(s) # show what our target looks like

    if s == buffer:

        print 'Bingo !!!'

        ar.tofile(port) # luckily there is this method,

        port.flush() # so we don't have to convert back to string...



This lot was cut and pasted from the little test program I am using to debug the port stuff - there may be tab issues - the question I suppose has to do with the types that the xor supports, and I suppose I am saying that it would be nice if a single byte string (also from an iterator) would be supported by the xor operator... ( maybe a single char string...there's a difference between ascii and unicode...)

As my program stands it works, but it seems long - winded and ugly....

- Hendrik van Rooyen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20060514/ea17ecff/attachment.html>


More information about the Python-list mailing list