更新时间:2024-04-12 GMT+08:00

开发示例

本节主要以C语言进行示例,指导客户端开发人员如何在客户端实现UDP水印的计算和添加,开发人员可以根据实现开发平台进行代码调整。

计算CRC哈希值代码示例

本章节的CRC算法使用CRC-32-IEEE 802.3。

  • 初始化CRC表:
unsigned int g_szCRCTable[256];
void CRC32TableInit(void)
{
    unsigned int c;
    int n, k;
    for (n = 0; n < 256; n++) {
        c = (unsigned int)n;
        for (k = 0; k < 8; k++) {
            if (c & 1) {
                c = 0xedb88320 ^ (c >> 1);
            }
            else {
                c = c >> 1;
            }
        }
        g_szCRCTable[n] = c;
    }
}
  • 计算CRC哈希值的接口,其中第一个参数crc默认使用0即可。
unsigned int CRC32Hash(unsigned int crc, unsigned char* buf, int len)
{
    unsigned int c = crc ^ 0xFFFFFFFF;
    int n; 
    for (n = 0; n < len; n++) {
        c = g_szCRCTable[(c ^ buf[n]) & 0xFF] ^ (c >> 8);
    } 
    return c ^ 0xFFFFFFFF;
}

计算报文的水印值示例代码

计算水印信息结构如图1所示。

图1 计算水印信息结构图
  • 水印数据结构定义如下代码所示
typedef struct {
    unsigned int   userId;    /* 用户标识ID */
    unsigned int   payload;   /* 业务载荷 */
    unsigned short destPort;  /* 业务目的端口 */
    unsigned short rsv;       /* 保留字段,2字节填充 */
    unsigned int   destIp;    /* 业务目的IP */
    unsigned int   key;       /* 水印关键字 */
} UdpWatermarkInfo;
  • 字节序需要使用网络序。
  • 业务载荷不满4字节的,使用0进行填充。
  • 计算CRC哈希值可以使用CPU硬件加速接口进行替换,以提升处理性能。
unsigned int UdpFloodWatermarkHashGet(unsigned int userId, unsigned int payload, unsigned short destPort, unsigned int destIp, unsigned int key)
{
    UdpWatermarkInfo stWaterInfo;

    stWaterInfo.destIp   = destIp;
    stWaterInfo.destPort = destPort;
    stWaterInfo.userId   = userId;
    stWaterInfo.payload  = payload;
    stWaterInfo.key      = key;
    stWaterInfo.rsv      = 0;

    return CRC32Hash(0, (UCHAR *)&stWaterInfo, sizeof(stWaterInfo));
}

填充报文UDP水印

将计算出的CRC哈希值,按图2结构填充到报文中,然后发送出去。

图2 填充报文UDP水印