uniqueiv.c
上传用户:fubang
上传日期:2009-06-18
资源大小:2071k
文件大小:4k
源码类别:

其他

开发平台:

Unix_Linux

  1. /*
  2.  *  IV uniqueness detection method, as designed by Stanislaw Pusep:
  3.  *
  4.  *  Each IV byte is stored in corresponding "level". We have 3 levels with
  5.  *  IV[2] as root index (level 0), IV[1] and IV[2] as level 2 and level 1
  6.  *  indices respectively. Space required to allocate all data is at maximum
  7.  *  2^24/8 (2 MB) and space required by filled index structures is 257 KB.
  8.  */
  9. #include <stdlib.h>
  10. #define IV_NOTHERE  0
  11. #define IV_PRESENT  1
  12. /* select byte within which desired bit is located */
  13. #define BITWISE_OFFT(x)         (x >> 3)
  14. /* mask to extract desired bit */
  15. #define BITWISE_MASK(x)         (1 << (x & 7))
  16. /* allocate root structure */
  17. unsigned char **uniqueiv_init( void )
  18. {
  19.     int i;
  20.     /* allocate root bucket (level 0) as vector of pointers */
  21.     
  22.     unsigned char **uiv_root = (unsigned char **)
  23.         malloc( 256 * sizeof( unsigned char * ) );
  24.     
  25.     if( uiv_root == NULL )
  26.         return( NULL );
  27.     /* setup initial state as empty */
  28.     for( i = 0; i < 256; i++ )
  29.         uiv_root[i] = NULL;
  30.     return( uiv_root );
  31. }
  32. /* update records with new IV */
  33. int uniqueiv_mark( unsigned char **uiv_root, unsigned char IV[3] )
  34. {
  35.     unsigned char **uiv_lvl1;
  36.     unsigned char  *uiv_lvl2;
  37.     short i;
  38.     if( uiv_root == NULL )
  39.         return( 0 );
  40.     /* select bucket from level 1 */
  41.     uiv_lvl1 = (unsigned char **) uiv_root[IV[2]];
  42.     /* create if it doesn't exists */
  43.     if( uiv_lvl1 == NULL )
  44.     {
  45.         /* allocate level 2 bucket being a vector of bits */
  46.         uiv_lvl1 = (unsigned char **) malloc( 256 * sizeof( unsigned char * ) );
  47.         if( uiv_lvl1 == NULL )
  48.             return( 1 );
  49.         /* setup initial state as empty */
  50.         for( i = 0; i < 256; i++ )
  51.             uiv_lvl1[i] = NULL;
  52.         /* link to parent bucket */
  53.         uiv_root[IV[2]] = (unsigned char *) uiv_lvl1;
  54.     }
  55.     /* select bucket from level 2 */
  56.     uiv_lvl2 = (unsigned char *) uiv_lvl1[IV[1]];
  57.     /* create if it doesn't exists */
  58.     if( uiv_lvl2 == NULL )
  59.     {
  60.         /* allocate level 2 bucket as a vector of pointers */
  61.         uiv_lvl2 = (unsigned char *) malloc( 32 * sizeof( unsigned char ) );
  62.         if( uiv_lvl1 == NULL )
  63.             return( 1 );
  64.         /* setup initial state as empty */
  65.         for( i = 0; i < 32; i++ )
  66.             uiv_lvl2[i] = 0;
  67.         /* link to parent bucket */
  68.         uiv_lvl1[IV[1]] = uiv_lvl2;
  69.     }
  70.     /* place single bit into level 2 bucket */
  71.     uiv_lvl2[BITWISE_OFFT( IV[0] )] |= BITWISE_MASK( IV[0] );
  72.         
  73.     return( 0 );
  74. }
  75. /* check if already seen IV */
  76. int uniqueiv_check( unsigned char **uiv_root, unsigned char IV[3] )
  77. {
  78.     unsigned char **uiv_lvl1;
  79.     unsigned char  *uiv_lvl2;
  80.         
  81.     if( uiv_root == NULL )
  82.         return( IV_NOTHERE );
  83.     /* select bucket from level 1 */
  84.     uiv_lvl1 = (unsigned char **) uiv_root[IV[2]];
  85.     /* stop here if not even allocated */
  86.     if( uiv_lvl1 == NULL )
  87.         return( IV_NOTHERE );
  88.     /* select bucket from level 2 */
  89.     uiv_lvl2 = (unsigned char *) uiv_lvl1[IV[1]];
  90.     /* stop here if not even allocated */
  91.     if( uiv_lvl2 == NULL )
  92.         return( IV_NOTHERE );
  93.     /* check single bit from level 2 bucket */
  94.     if( ( uiv_lvl2[ BITWISE_OFFT( IV[0] ) ]
  95.                   & BITWISE_MASK( IV[0] ) ) == 0 )
  96.         return( IV_NOTHERE );
  97.     else
  98.         return( IV_PRESENT );
  99. }
  100. /* unallocate everything */
  101. void uniqueiv_wipe( unsigned char **uiv_root )
  102. {
  103.     int i, j;
  104.     unsigned char **uiv_lvl1;
  105.     unsigned char  *uiv_lvl2;
  106.         
  107.     if( uiv_root == NULL )
  108.         return;
  109.     /* recursively wipe out allocated buckets */
  110.     for( i = 0; i < 256; i++ )
  111.     {
  112.         uiv_lvl1 = (unsigned char **) uiv_root[i];
  113.         if( uiv_lvl1 != NULL )
  114.         {
  115.             for( j = 0; j < 256; j++ )
  116.             {
  117.                 uiv_lvl2 = (unsigned char *) uiv_lvl1[j];
  118.                 if( uiv_lvl2 != NULL )
  119.                     free( uiv_lvl2 );
  120.             }
  121.             free( uiv_lvl1 );
  122.         }
  123.     }
  124.     free( uiv_root );
  125.     return;
  126. }