Previous: uticr Up: ../plot79_u.html Next: utida


UTICRC

       INTEGER FUNCTION  UTICRC (CHKSUM,BYTE)
 C$    (CRC-16 Checksum Accumulation)
 C$    Accumulate  a  CRC-16  cyclic  redundancy  checksum.    The
 C$    INTEGER arguments, neither of which are modified, are:
 C$
 C$    CHKSUM.........Current checksum  value.  It should be 0 for
 C$                   the first byte of a cumulative sequence, and
 C$                   set to the last  returned function value  on
 C$                   subsequent calls.
 C$    BYTE...........Byte  value to be  included in the checksum.
 C$                   Only the low-order 8 bits are used.
 C$
 C$    The updated checksum  returned as the  function value is  a
 C$    16-bit quantity,  and it  is  required that  INTEGER  words
 C$    contain at least 16 bits.
 C$
 C$    Cyclic  redundancy   checksums  are   superior  to   simple
 C$    checksums obtained by adding or exclusive-OR'ing data  byte
 C$    sequences.   Such  methods  cannot  detect  bytes  out   of
 C$    sequence and can fail to detect even two single-bit errors,
 C$    such as in two  consecutive bytes with  an inverted bit  in
 C$    the same position.
 C$
 C$    By contrast, the  CRC-CCITT used by  the ANSI X.25,  ADCCP,
 C$    HDLC, and IBM's SDLC protocols  detects error bursts up  to
 C$    16 bits in length, and  99 percent of error bursts  greater
 C$    than 12 bits.   The CRC-16  used by DDCMP  and Bisync,  and
 C$    implemented here, detects error bursts  up to 16 bits,  and
 C$    99 percent of bursts greater than 16 bits in length.
 C$
 C$    The associated  CRC  polynomial  is  written  in  order  of
 C$    increasing powers of  2 and  1-bits are  assigned for  each
 C$    non-zero polynomial coefficients at corresponding positions
 C$    in a 16-bit word with bit  numbering 0 (high) to 15  (low),
 C$    discarding any bits outside the word.
 C$
 C$    Two common CRC polynomials are
 C$
 C$    Bit positions:                                    11 1111 1
 C$                                          0123 4567 8901 2345 6
 C$                     2    15    16                 discard ---v
 C$    CRC-16:     1 + x  + x   + x      ==> 1010 0000 0000 0001 1
 C$
 C$                     5    12    16                 discard ---v
 C$    CRC-CCITT:  1 + x  + x   + x      ==> 1000 0100 0000 1000 1
 C$
 C$    giving the following values in bases 8, 10, and 16:
 C$
 C$    CRC-16    constant = 8#120001 = 10#40961 = 16#A001
 C$    CRC-CCITT constant = 8#102010 = 10#33800 = 16#8408
 C$
 C$    Simple code for the CRC accumulation looks as follows  (all
 C$    variables being INTEGERs  of 16  or more  bits).  Only  the
 C$    constant CRCCON  changes according  to the  CRC  polynomial
 C$    used.  This is slow in  software but is easily  implemented
 C$    by hardware shift registers and XOR gates.
 C$
 C$    DATA                CRCCON    / 40961 /
 C$
 C$    TEMP = IBTAND(BYTE,255)
 C$    TEMP = IBTXOR(TEMP,CHKSUM)
 C$    DO FOR BIT = 0,7
 C$         BITLO = IBTAND(TEMP,1)
 C$         TEMP = IBTSHR(TEMP,1)
 C$         IF (BITLO .EQ. 1) TEMP = IBTXOR(TEMP,CRCCON)
 C$    END FOR
 C$    CRC = TEMP
 C$
 C$    That is,  after exclusive-OR'ing  the 8-bit  byte with  the
 C$    current checksum,  each  of the  low-order  8 bits  of  the
 C$    result is  used  to determine  whether  or not  to  perform
 C$    another exclusive-OR  of the  shifted  value with  the  CRC
 C$    constant.  With CRC-16, CHKSUM  is initially 0, while  with
 C$    CRC-CCITT, CHKSUM must  be initialized to  all 1 bits.   On
 C$    subsequent calls, CHKSUM must  be replaced by the  function
 C$    value CRC.
 C$
 C$    By preprocessing, it is possible  to reduce the inner  loop
 C$    to 4  steps  using  shifts of  2  bits  and a  table  of  4
 C$    constants, 2 steps using shifts of 4 bits and a table of 16
 C$    constants, and 1 step (used here)  using a shift of 8  bits
 C$    and a table of 256 constants.  SFTRAN3 implementations of 3
 C$    of these 4  alternatives on the  DEC-20/60 had timings  (in
 C$    microsec/byte) of about 152 (8-step)  to 57 (2-step) to  40
 C$    (1-step).    An   efficient   1-step   assembly    language
 C$    implementation on  the  same machine  with  a  compile-time
 C$    constant table  required only  7.9 microsec/byte  and  took
 C$    only 8 instructions.
 C$
 C$    Implementation Note:
 C$
 C$    In order  to achieve  machine  independence, the  table  of
 C$    constants is  constructed at  run-time on  the first  call,
 C$    since it contains values which when represented as positive
 C$    decimal integers require 16 data bits.  On 16-bit machines,
 C$    only 15 data bits are available for positive integers.   If
 C$    the host FORTRAN does  not preserve local variables  across
 C$    subroutine calls, then UNSET and TABLE should be placed  in
 C$    COMMON (if this  would preserve them),  or referenced in  a
 C$    FORTRAN 77  SAVE  statement.   For  checking  purposes,  or
 C$    system-dependent modifications  which change  the  run-time
 C$    initialization  to  compile-time  initialization  via  DATA
 C$    statements, the  actual values  of  the table  entries  are
 C$    given below in comments.
 C$    (03-OCT-85)