二十四進制編碼串轉換為32位無符號整數(C語言實現)
阿新 • • 發佈:2017-05-12
bool while open 參數錯誤 hint div 第一個字符 bsp opened
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‘, ‘8View Code‘, ‘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分二十四進制編碼串轉換為32位無符號整數(C語言實現)