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值(桶, 拉链)上进行内存字节的比较就可以解决。

  • 相关阅读:
    Windows netsh命令的使用
    源码安装 qemu-2.0.0 及其依赖 glib-2.12.12
    .ko文件
    Suse环境下编译linux-2.6.24内核
    cut
    POJ3648 Wedding
    [Hnoi2010]Planar
    [中山市选2011]杀人游戏
    BZOJ3033 太鼓达人
    POJ1041 John's trip
  • 原文地址:https://www.cnblogs.com/xudong-bupt/p/8526340.html
Copyright © 2011-2022 走看看