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; }
点评:
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分
时间: 2024-10-13 06:19:00