1. 程式人生 > >二十四進制編碼串轉換為32位無符號整數(C語言實現)

二十四進制編碼串轉換為32位無符號整數(C語言實現)

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, 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語言實現)