ASTM校验和计算

时间:2016-11-28 06:23:28

标签: c# asp.net

我需要了解设备如何计算以下ASTM字符串的校验和

<STX2P|1|||||||||||||||||||||||||||||||||<CR><ETX>3B<CR><LF>

此字符串显示校验和为“3B”,而我试图通过以下代码查找校验和

    public static string ConvertStringToHex(string asciiString)
    {
        string hex = "";
        foreach (char c in asciiString)
        {
            int tmp = c;
            hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
        }
        return hex;
    }

但我得到“3C”作为输出。请帮助我如何找到校验和。

1 个答案:

答案 0 :(得分:0)

如何计算ASTM中的校验和......

  

通过添加字符的二进制值来计算校验和,   保持结果的最低8位。   消息文本中的每个字符都被添加到校验和中(模256)。   校验和是由8位表示的整数,可以认为是两组,每组4位。   四位组转换为十六进制表示的ASCII字符。   两个ASCII字符作为校验和传输,首先是最重要的字符。

我把这行放在文件3B中并运行了我将在本节下面发布的脚本。我不得不添加&gt;用于修复STX字符串的标志。

  

leopard:astm rene $ ./astm.sh ./3B起始./astm.sh ......

     

2P | 1 ||||||||||||||||||||||||||||||||| 3B

     

1000100111011 L8B = 111011   LSB用于计算MOD 256 L8B

     

MOD = 00111011

     

并且校验和是.......

     

MOD = 00111011 M4B = 0011

     

---&gt; L4B = 1011

     

校验= 3B

#! /bin/ksh
#set -x

#
############################# Variables #######################
#
integer i=0
HEX=00
integer LEN=0
integer FROM=0
MESSAGE=$1
#blind=0 Not blind
#blind=1 blind, it does not see any astm character till it can see again (blind=0)
HEXTMP=/tmp/hex.tmp
BINTMP=/tmp/bin.tmp
#
############################# Functions #######################
#

astm_checksum() {
print"
# The checksum is computed by adding the binary values of the characters,
# keeping the least significant eight bits of the result.
# Each character in the message text is added to the checksum (modulo 256).
# The checksum is an integer represented by eight bits, it can be considered as two groups of four bits.
# The groups of four bits are converted to the ASCII characters of the hexadecimal representation.
# The two ASCII characters are transmitted as the checksum, with the most significant character first.
"
#converting text in Variable VAR to binairy ...
}


code2hex() {    #Read and convert text written with codes in ASCII like <STX>
printf "\n\n"
awk '
!/^#/   {
        gsub(/<NUL>/,"\x00",$0 )
        gsub(/<SOH>/,"\x01",$0 )
        gsub(/<STX>/,"\x02",$0 )
        gsub(/<ETX>/,"\x03",$0 )
        gsub(/<EOT>/,"\x04",$0 )
        gsub(/<ENQ>/,"\x05",$0 )
        gsub(/<ACK>/,"\x06",$0 )
        gsub( /<LF>/,"\x0A",$0 )
        gsub( /<FF>/,"\x0C",$0 )
        gsub( /<CR>/,"\x0D",$0 )
        gsub(/<NAK>/,"\x15",$0 )
        gsub(/<SYN>/,"\x16",$0 )
        gsub(/<ETB>/,"\x17",$0 )
        gsub(/<CAN>/,"\x18",$0 )
        gsub(/<ESC>/,"\x1B",$0 )
        printf( $0 "\n" )
}
' ${MESSAGE} | hd | cut -c11-58 | tr [:lower:] [:upper:] | xargs | tee ${HEXTMP} | awk '
#example output, one line due to xargs
#02 31 48 7C 5C 5E 26 7C 7C 7C 50 5E 31 7C 7C 7C 7C 7C 7C 7C 50 7C 31 7C 0D 03 31 35 0D 0A
#--- first part to filter out control data from real data ---
BEGIN{ RS=" "; blind = 0 ; printf "ibase=16 ; obase=2 ;scale=0;" }
/0A/            { next }                        # <LF>

/02/            { printf("00+"); blind = 0      # <STX>
                } #Eyes are opened (again), after <STX> we start counting
!/02/ && !/03/  { if ( blind == 0 )             
                        printf( $0"+" )
                } #This also includes the <CR> (0D) BEFORE the ETX or ETB!!!
/03/ || /17/    { if ( blind == 0 ) {           
                        printf( $0"\n" ) 
                        blind = 1   }           #The \n = end line and calculate
                } #Blind.. we see nothing till a <STX> is passing again
'| sed 's/+$/\n/p' | tee -a ${HEXTMP} | bc -q | tee ${BINTMP} | while read BIN
do
        #       The two files tee writes to is for debugging only.
        #       
        #       % in bc is modulo but is not described clearly in the man page
        #       scale is default set to 0 but I set it anyway to be sure.
        #
        #Binairy
        printf "BIN= %08d\n" ${BIN}
        #Calculate from where we need to cut the string of bits to have the LSB 8 bits
        LEN=$(echo ${BIN} | wc -c )                     #Not supported by the QNX Shell
        FROM=$(( LEN - 8 ))                             #Not supported by the QNX Shell
        L8B=$(echo ${BIN} | cut -c ${FROM}- )
        printf "L8B=%${LEN}d\n" ${L8B}

        printf "LSB used to calculate the MOD 256\n"
        MOD=$(  echo "ibase=2 ; obase=2 ; ${L8B} % 100000000" | bc -q ) #LSB SUM
        printf "L8B MOD= %08d\n" ${MOD}

        printf "--------------------------- and the checksum is.......  \n"
        printf "MOD= %08d\n" ${MOD}
        M4B=$( printf "%08d\n" ${MOD} | cut -c -4 )
        L4B=$( printf "%08d\n" ${MOD} | cut -c 5- )
        printf "M4B= $M4B\n--->L4B= $L4B\n"
        CD1=$(printf "ibase=2 ; obase=10000 ; ${M4B}\n" | bc -q )
        CD2=$(printf "ibase=2 ; obase=10000 ; ${L4B}\n" | bc -q )
        printf "Checksum=${CD1}${CD2}\n\n"
done
}

############################# main part ################################
test -r "${MESSAGE}" && (echo "Starting $0 ...";cat ${MESSAGE};code2hex) || echo "ERROR: Cannot read file ${MESSAGE}."