Base16具有自定义hextable

时间:2012-03-31 20:43:19

标签: c ios hex

我想使用Base16编码/解码数据但使用自定义hextable(与传统的'0123456789ABCDEF'相反)

我考虑过在写完之后简单地用相应的数字/字母替换每个数字/字母,但我发现效率低下显而易见原因

这适用于iphone应用程序,这意味着我使用的是Objective-c代码,但C和C ++也可以使用它。

我在这里尝试了代码:http://www.koders.com/c/fid4FE13B3E182CA09D7F399059A96DBF0A7968BA5C.aspx?s=base64

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <string.h>
#include <stdlib.h>

#include "ggz.h"
#include "base16.h"

/* Function to encode strings to base16 (hex) with a nibble per hex character */

char *ggz_base16_encode(const char *text, int length)
{
    char *ret = NULL;
    int i;
    static const char hextable[20] = "0123456789abcdef";

    if(!text) return NULL;

    ret = ggz_malloc((length * 2 + 1)*sizeof(*ret));
    if(!ret) return NULL;

    for(i = 0; i < length; i++){
        ret[i*2] = hextable[(text[i]&0xf0)>>4];
        ret[i*2+1] = hextable[text[i]&0xf];
    }
    return ret;
}

但是我没有在同一个网站上找到解码方法,也没有找到解决方法。这是我相应的Objective-c代码:

NSString *txt = @"hello";
NSData *data = [txt dataUsingEncoding:NSUTF8StringEncoding];
const char *nc = ggz_base16_encode(data.bytes, [data length]);
NSString *str = [[NSString alloc] initWithCString:nc encoding:NSUTF8StringEncoding];
}

非常感谢帮助。

由于

3 个答案:

答案 0 :(得分:0)

解码代码应该很简单,就像那样:

int result = 0;
for each char c in string (left to right)
    result = result * 16 + getNumericValue(c)

(伪!)

对于getNumericValue,一般来说,我会使用预先填充的地图(字典/散列表/您喜欢的语言),它只将char映射到其数值。

对于传统的十六进制表示法,可以按如下方式构建地图:

for (int i = '0'; i <= '9'; i++)
    map[i] = i - '0';
for (int i = 'a'; i <= 'f'; i++)
    map[i] = i - 'a' + 10;

- 但是对于你的特殊地图,你需要你的习惯表。

(我不是目标C的专家,所以我不知道那里有什么合适的数据结构。)

答案 1 :(得分:0)

我不确定这是否编译,它是用C. ggz_malloc模拟进行垃圾收集?

char * ggz_base16_decode(const char *text)
{
    const char * customtable = "0123456789abcdef";
    int size = strlen(text);
    char * ret = ggz_malloc((size+1)>>1);
    char * q = ret;
    int i;
    int f = 1;
    unsigned char t[256];
    memset(t,0,256);
    i = 0; while (*customtable) t[*customtable++]=i++;
    while (*text) {
            if (f) *q = t[*text]<<4;
            else *q++ |= t[*text];
            f = !f;
            ++text;
    }
    return ret;
}

答案 2 :(得分:0)

我想知道表达式

ret[i*2] = hextable[(text[i]&0xf0)>>4];

可能会出错。我认为char已签名。

如果text[i]的最高位设置为0xe0,则0xe0 & 0xf0 = 0xe00xe0 >> 40xfe因为它是符号扩展。所以它会超越hextable的结束。

所以试试

ret[i*2] = hextable[(text[i]>>4)&0x0f];