二十四进制编码串转换为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;
}

点评:

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

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

24、蛤蟆的数据结构笔记之二十四串的模式匹配算法

24.蛤蟆的数据结构笔记之二十四串的模式匹配算法 本篇名言:"燧石受到的敲打越厉害,发出的光就越灿烂. -- 马克思" 来看下两个算法,BF和KMP算法在串的模式匹配中实现. 欢迎转载,转载请标明出处: 1.  BF算法 BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果.B

实验二十四:SD卡模块

  驱动SD卡是件容易让人抓狂的事情,驱动SD卡好比SDRAM执行页读写,SD卡虽然不及SDRAM的麻烦要求(时序参数),但是驱动过程却有猥琐操作.除此此外,描述语言只要稍微比较一下C语言,描述语言一定会泪流满面,因为嵌套循环,嵌套判断,或者嵌套函数等都是它的痛.. 史莱姆模块是多模块建模的通病,意指结构能力非常脆弱的模块,暴力的嵌套行为往往会击垮模块的美丽身躯,好让脆弱结构更加脆弱还有惨不忍睹,最终搞垮模块的表达能力.描述语言预想驾驭SD卡,关键的地方就是如何提升模块的结构能力.简单而言,描述

winform学习日志(二十四)----------datetime和timer的使用(小小幻灯片)

一:展示图片 每秒换一次图片,一共六十张图片,00-59 二:代码 a,设计代码 namespace timePicture { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源. /// </summary

c# 字符串(含有汉字)转化为16进制编码(转)

public static string Str2Hex(string s) { string result = string.Empty; byte[] arrByte = System.Text.Encoding.GetEncoding("GB2312").GetBytes(s); for(int i = 0; i < arrByte.Length; i++) { result += "&#x" + System.Convert.ToString(

java中把字节数组为16进制字串

把字符串数组转换为16进制字符串 import java.security.MessageDigest; public class StringUtil { public StringUtil() { super(); } public static String str; public static final String EMPTY_STRING = ""; private final static String[] hexDigits = { "0", &q

QT开发(二十四)——QT文件操作

QT开发(二十四)--QT文件操作 一.QT文件操作简介 QT中的IO操作通过统一的接口简化了文件与外部设备的操作方式,QT中文件被当作一种特殊的外部设备,文件操作与外部设备操作相同. 1.IO操作的主要函数接口 打开设备:bool open(OpenMode mode) 读取数据:QByteArray read(qint64 maxSize) 写入数据:qint64 write(const QByteArray & byteArray) 关闭设备:void close() IO操作的本质是连续

二十四孝,图文并茂,古今必读!

知道“二十四孝”的人,已经不多了:知道“二十四孝”的年轻人,更是少之又少.“孝”在今日社会,似乎已是一个“过气”的词,人老珠黄般,逗不起众人的欲望了.我们读<二十四孝>,感觉那似乎是十分遥远的故事.其实细细想来,它好像又近在咫尺,离我们并不远. 01 孝感动天 舜,传说中的远古帝王,五帝之一,姓姚,名重华,号有虞氏,史称虞舜.相传他的父亲瞽叟及继母.异母弟象,多次想害死他:让舜修补谷仓仓顶时,从谷仓下纵火,舜手持两个斗笠跳下逃脱:让舜掘井时,瞽叟与象却下土填井,舜掘地道逃脱.事后舜毫不嫉恨,仍

二十四、管道符和作业控制、shell变量、环境变量配置文件

二十四.管道符和作业控制.shell变量.环境变量配置文件一.管道符和作业控制管道符:| 表示把前面文件输出的内容传递给后面的命令.|grep:过滤,指定关键词的命令.|grep 'aaa'.作业控制Ctrl+z:暂停一个任务.等于把当前任务放在了后台,使用fg命令再调回任务里.fg:前台,foreground.bg:后台,将任务调到后台去运行.示例: vim /etc/passwd [1]+ 已停止 vim /etc/passwd可以停止多个任务,被暂停的任务会有编号.想调回哪个就fg 1或者

从零开始学android&lt;android事件的处理方式.二十四.&gt;

在android中一共有 多种事件,每种事件都有自己相对应的处理机制 如以下几种 1 单击事件 View.OnClickListener public abstract void onClick (View v) 单击组件时触发 2 单击事件 View.OnLongClickListener public abstract boolean onLongClick (View v) 长按组件时触发 3 键盘事件 View.OnKeyListener public abstract boolean