zoukankan      html  css  js  c++  java
  • 一次问题追查----短字符串签名算法引发的bug

    近期开发代码, 出现了一些诡异现象。追查原因是公司使用的签名函数出现的问题。

    问题: 代码使用的签名库函数, 对于<=4字节的字符串, 签名就是本身。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 
     5 int main(){
     6     char str[128] = "ni";   //长度是2
     7     unsigned num[1];    //长度是4
     8     memset(num, 0, sizeof(unsigned));
     9     memcpy(num, str, strlen(str));  //num[0] = 26990
    10     
    11     //可以看出, str, num 在前3个字节的内存是相等的
    12     printf("tag = %d
    ", memcmp(num, str, strlen(str) + 1));    //把也算进去
    13 
    14     //对于使用的优化后的签名函数, <= 4个字节则签名为本身(12的签名还是12)
    15     //出现的bug是:
    16     //str:ni, len:3 ---> sign:26990
    17     //num:26990, len:4 ---> sign:26990
    18     return 0;   
    19 }

    hash函数只是计算签名, 有时会有hash冲突导致实际不相等的字符串, 有相同的hash值。

    如果要严格比较, 可以直接比较内存字节。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 
     5 int is_eq(
     6         const void* addr1, int len1,
     7         const void* addr2, int len2){
     8     if (len1 != len2){
     9         return 1;
    10     }   
    11     return memcmp(addr1, addr2, len1) == 0? 0:1;
    12 }
    13 
    14 int main(){
    15     char str[128] = "ni";   //长度是2
    16     unsigned num[1];    //长度是4
    17     num[0] = 26990;
    18     
    19     //把字符串的结尾也计算进去
    20     printf("tag = %d
    ", is_eq(str, strlen(str) + 1, num, sizeof(num)));
    21     return 0;   
    22 }

    在严格场景下, 可以先用hash做签名, 之后再具体到每个hash值(桶, 拉链)上进行内存字节的比较就可以解决。

  • 相关阅读:
    NET6 如何使用Windows Service
    Delphi 设置窗体无标题栏和边框
    java MD5 加密 及对应的 oracle数据库中的MD5加密实现
    oracle 查看锁表进程和解锁
    创建dblink 及 同义词
    demjson python key没有引号的字符串如何转json
    Typescript Objects对象
    typescrip 数组、Map、对象方法
    mysql 日期 时间函数
    Typesrcipt日期时间
  • 原文地址:https://www.cnblogs.com/xudong-bupt/p/8526340.html
Copyright © 2011-2022 走看看