【问题标题】:checksum for UTF-8 stringUTF-8 字符串的校验和
【发布时间】:2017-08-10 01:36:05
【问题描述】:

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

这是 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");
        }
    }
}

【问题讨论】:

  • 你应该在这里发布代码而不是链接。
  • 谢谢。我已经发布了。
  • 具体遇到了什么问题? ASCII 的校验和本质上是字节的校验和。因此,您可以只取 UTF8 字节并对它们进行校验和。你为什么要计算校验和?您是否需要遵守某些特定的校验和实现?这是某种学术活动吗?
  • 您是如何在 ASCII 字符串的实现中验证校验和的?如果您计算 UTF-8 字符串的校验和并尝试以相同的方式验证校验和,会发生什么情况?
  • 校验和用于应用级别的 SIP2 消息错误检测。 SIP2是图书馆自动化系统与自动化设备之间的通信协议。我的问题中已经描述了校验和算法。协议通讯使用TCP Socket。

标签: c# encoding utf-8


【解决方案1】:

替换代码

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

chrArray[intCtr]是输入ASCII字符串,以十进制输出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 字符可以超过一个字节。

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 2015-06-02
    • 2012-04-07
    • 2023-03-27
    • 1970-01-01
    • 2017-03-04
    • 2015-01-19
    • 1970-01-01
    相关资源
    最近更新 更多