首页 > 代码库 > 二十四进制编码串转换为32位无符号整数(C语言实现)

二十四进制编码串转换为32位无符号整数(C语言实现)

技术分享
typedef int BOOL;
#define TRUE  1;
#define FALSE 0;

#define UINT_MAX      0xffffffff    /* maximum unsigned int value */

enum Scale24AsciiVal
{
   sav_aADis    = 32,  // 小写字母与大写字母ASCII码差值
   sav_chIntDis = 48,  // 字符‘0’ASCII码值
};

static const char scale24[24] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B,
                                 C, F, H, K, M, P, S, T, U, W, X, Y};

// 判断是否为合法的二十四进制编码字符
BOOL IsScale24(const char ch, unsigned int* nVal);

/*
二十四进制编码串转换为32位无符号整数, 其中:
参数:
  str      二十四进制编码串
  length   二十四进制编码串长度, 若 < 0 则为 str 以 ‘\0‘ 结尾
  code     转换返回码, 若 code == NULL 则忽略返回码
返回值:
  (值)     转换后的返回值, 转换是否成功从 code 得到。
*/
unsigned int C24ToU32(const char* str, int length, int* code)
{
  unsigned int result = 0;
  const char*  pStr   = str;
  unsigned int nVal   = 0; // 位值
  int codeIdx  = 1;        // 非法字符在编码串中的序号
  
  if (code != NULL)  *code = 0; 

  if( (pStr==NULL) || ((pStr=="") && (length==0)) )
  {
     if (code != NULL)
       *code = -1;    // 转换失败, 可能参数错误或字符串为空串
  }
  else
  {
     if(length < 0)   // str 以 ‘\0‘ 结尾
     {
        while(*pStr != \0)
        {
           if(IsScale24(*pStr, &nVal))
           {
              if ( ((UINT_MAX-nVal)/24) < result ) // 转换失败(溢出)
              {
                 if (code != NULL)
                    *code = codeIdx; 
                 break;
              }
              else
                 result = result*24 + nVal;       // 进位并加位值
           } 
           else
           {
              if (code != NULL)
                 *code = codeIdx; // 转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码
              break;
           }
           codeIdx ++;
           pStr ++;
        }
     }
     else
     {
        while(codeIdx <= length)
        {
           if(IsScale24(*pStr, &nVal))
           {
              if ( ((UINT_MAX-nVal)/24) < result ) // 转换失败(溢出)
              {
                 if (code != NULL)
                    *code = codeIdx;
                 break;
              }
              else
                 result = result*24 + nVal;       // 进位并加位值
           }
           else
           {
              if (code != NULL)
                 *code = codeIdx; // 转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码
              break;
           }

           codeIdx ++;
           pStr ++;
        }
     }
  }
  return result;
}

/*
判断是否为合法的二十四进制编码字符, 其中:
参数:
  ch       待判定字符
  nVal     ch若合法,则nVal为ch所对应的二十四进制字符位值(‘A‘->10,‘B‘->11,‘C‘->12...)
返回值:
  (值)     ch合法->true,非法->false。
*/
BOOL IsScale24(const char ch, unsigned int* nVal)
{
   BOOL result = FALSE;

   unsigned int nbegin  = 10;  // 二分查找ch,初始起始位置
   unsigned int nEnd    = 23;  // 二分查找ch,初始结束位置
   unsigned int nMid    = 16;  // 二分查找ch,初始折半位置
   unsigned int nOffset = 0;
   char chScale= 0;

   if((ch >= 0) && (ch <=9))  // ‘0‘...‘9‘
   {
      *nVal  = (unsigned int)(ch-sav_chIntDis);
      result = TRUE;    
   }
   else if (ch >= A && ch <= y)
   {
      if (ch > Z) // ch为小写字母
         nOffset = sav_aADis;

      // ‘A(a)‘...‘Y(y)‘ 二分查找ch
      while ( nbegin <=  nEnd ){
           chScale = scale24[nMid] + nOffset;
         if ( chScale == ch )
         {
            *nVal  = nMid;
            result = TRUE;
            break;
         }
         else if ( chScale > ch )
            nEnd   = nMid - 1;
         else
            nbegin = nMid + 1;

         nMid = (nbegin + nEnd) / 2;
      }
   }
   return result;
}
View Code

点评:

   1. if((pStr==NULL) || ((pStr=="") && (length==0))) 判断错误的 bug, 应该为:
      if ((pStr == NULL) || (length == 0) || ((length < 0) && (*pStr == ‘\0‘)))
   2. if (((UINT_MAX-nVal)/24) < result) 判断溢出有漏洞的 bug;
   3. IsScale24(const char ch, unsigned int* nVal) 查找效率不够好, 可以把小写字
      母也放在数组中, 全部进行二分查找, 这样可以减少判断;
   4. 评分: 75分

二十四进制编码串转换为32位无符号整数(C语言实现)