2017-08-10 148 views
-2

下面是校验和说明。 校验和是四个ASCII字符数字,表示字符的二进制和,包括传输的第一个字符,直到并包括校验和字段标识符字符。 要计算校验和,将每个字符添加为无符号二进制数,取总共的低16位并执行2的补码。校验和字段是由四个十六进制数字表示的结果。 要验证接收数据的正确校验和,只需添加包括校验和的所有十六进制值。它 应该等于零。UTF-8字符串校验和

这是ASCII字符串的实现,但现在我的输入字符串是UTF-8。 任何人都会提出一些想法来修改UTF-8编码的实现。非常感谢。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace SIP2 
{ 
    // Adapted from VB.NET from the Library Tech Guy blog 
    // http://librarytechguy.blogspot.com/2009/11/sip2-checksum_13.html 

    public class CheckSum 
    { 
     public static string ApplyChecksum(string strMsg) 
     { 
      int intCtr; 
      char[] chrArray; 
      int intAscSum; 
      bool blnCarryBit; 
      string strBinVal = String.Empty; 
      string strInvBinVal; 
      string strNewBinVal = String.Empty; 

      // Transfer SIP message to a a character array.Loop through each character of the array, 
      // converting the character to an ASCII value and adding the value to a running total. 

      intAscSum = 0; 
      chrArray = strMsg.ToCharArray(); 

      for (intCtr = 0; intCtr <= chrArray.Length - 1; intCtr++) 
      { 
       intAscSum = intAscSum + (chrArray[intCtr]); 
      } 

      // Next, convert ASCII sum to a binary digit by: 
      // 1) taking the remainder of the ASCII sum divided by 2 
      // 2) Repeat until sum reaches 0 
      // 3) Pad to 16 digits with leading zeroes 

      do 
      { 
       strBinVal = (intAscSum % 2).ToString() + strBinVal; 
       intAscSum = intAscSum/2; 
      } while (intAscSum > 0); 

      strBinVal = strBinVal.PadLeft(16, '0'); 

      // Next, invert all bits in binary number. 
      chrArray = strBinVal.ToCharArray(); 
      strInvBinVal = ""; 

      for (intCtr = 0; intCtr <= chrArray.Length - 1; intCtr++) 
      { 
       if (chrArray[intCtr] == '0') { strInvBinVal = strInvBinVal + '1'; } 
       else { strInvBinVal = strInvBinVal + '0'; } 
      } 


      // Next, add 1 to the inverted binary digit. Loop from least significant digit (rightmost) to most (leftmost); 
      // if digit is 1, flip to 0 and retain carry bit to next significant digit. 

      blnCarryBit = true; 
      chrArray = strInvBinVal.ToCharArray(); 

      for (intCtr = chrArray.Length - 1; intCtr >= 0; intCtr--) 
      { 
       if (blnCarryBit == true) 
       { 
        if (chrArray[intCtr] == '0') 
        { 
         chrArray[intCtr] = '1'; 
         blnCarryBit = false; 
        } 
        else 
        { 
         chrArray[intCtr] = '0'; 
         blnCarryBit = true; 
        } 
       } 
       strNewBinVal = chrArray[intCtr] + strNewBinVal; 
      } 

      // Finally, convert binary digit to hex value, append to original SIP message. 
      return strMsg + (Convert.ToInt16(strNewBinVal, 2)).ToString("X"); 
     } 
    } 
} 
+0

你应该在这里发布代码而不是指向它的链接。 – juharr

+0

谢谢。我已经发布了它。 – Felix

+1

你有什么特别的问题? ASCII的校验和本质上是一个字节的校验和。所以你可以只取UTF8字节和校验和。你为什么要计算校验和?是否需要遵守一些特定的校验和实施?这是一种学术运动吗? –

回答

0

替换代码

for (intCtr = 0; intCtr <= chrArray.Length - 1; intCtr++) 
{ 
    intAscSum = intAscSum + (chrArray[intCtr]); 
} 

chrArray[intCtr]被输入ASCII字符串OUPUT十进制的ASCII码,例如, “A” 是65 ASCII编码仅使用1个字节。 UTF-8使用一个字节或多个字节来表示UTF-8字符。我认为chrArray[intCtr]是为ASCII设计的 - 因此UTF-8(多于一个字节)的输入是不合理的。

随着

int i = 0; 
for (i = 0; i < bytes.Length; i++) 
{ 
    intAscSum = intAscSum + bytes[i]; 
} 
byte[] bytes = Encoding.UTF8.GetBytes(strMsg); 

添加了所有的字节,因为一个UTF8字符可以超过一个字节。