是否有任何标准C函数从十六进制字符串转换为字节数组?
我不想写自己的功能。
答案 0 :(得分:59)
据我所知,这样做没有标准功能,但以下列方式实现很简单:
#include <stdio.h>
int main(int argc, char **argv) {
const char hexstring[] = "DEadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
/* WARNING: no sanitization or error-checking whatsoever */
for (size_t count = 0; count < sizeof val/sizeof *val; count++) {
sscanf(pos, "%2hhx", &val[count]);
pos += 2;
}
printf("0x");
for(size_t count = 0; count < sizeof val/sizeof *val; count++)
printf("%02x", val[count]);
printf("\n");
return 0;
}
正如Al所指出的,如果字符串中有十六进制数字的奇数,则必须确保在其前面添加0开头。例如,字符串"f00f5"
将被计算为{{ 1}}错误地通过上面的例子,而不是正确的{0xf0, 0x0f, 0x05}
。
稍微修改了一下这个例子来解决@MassimoCallegari的评论
答案 1 :(得分:11)
我通过谷歌搜索发现了同样的问题。我不喜欢调用sscanf()或strtol()的想法,因为它感觉有点矫枉过正。我写了一个快速函数,它不验证文本确实是字节流的十六进制表示,但是将处理奇数个十六进制数字:
uint8_t tallymarker_hextobin(const char * str, uint8_t * bytes, size_t blen)
{
uint8_t pos;
uint8_t idx0;
uint8_t idx1;
// mapping of ASCII characters to hex values
const uint8_t hashmap[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // !"#$%&'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ()*+,-./
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PQRSTUVW
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XYZ[\]^_
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // `abcdefg
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // hijklmno
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pqrstuvw
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xyz{|}~.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ........
};
bzero(bytes, blen);
for (pos = 0; ((pos < (blen*2)) && (pos < strlen(str))); pos += 2)
{
idx0 = (uint8_t)str[pos+0];
idx1 = (uint8_t)str[pos+1];
bytes[pos/2] = (uint8_t)(hashmap[idx0] << 4) | hashmap[idx1];
};
return(0);
}
答案 2 :(得分:8)
对于短字符串,strtol
,strtoll
和strtoimax
将正常工作(请注意,第三个参数是用于处理字符串的基础...将其设置为16)。如果您的输入超过number-of-bits-in-the-longest-integer-type/4
,则您需要其他答案建议的更灵活的方法之一。
答案 3 :(得分:5)
除了上面的优秀答案,我会写一个不使用任何库的C函数,并且有一些防止坏字符串的保护。
uint8_t* datahex(char* string) {
if(string == NULL)
return NULL;
size_t slength = strlen(string);
if((slength % 2) != 0) // must be even
return NULL;
size_t dlength = slength / 2;
uint8_t* data = malloc(dlength);
memset(data, 0, dlength);
size_t index = 0;
while (index < slength) {
char c = string[index];
int value = 0;
if(c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A'));
else if (c >= 'a' && c <= 'f')
value = (10 + (c - 'a'));
else {
free(data);
return NULL;
}
data[(index/2)] += value << (((index + 1) % 2) * 4);
index++;
}
return data;
}
说明:
<强>一个。 index / 2 |整数之间的舍入将向下舍入该值,因此0/2 = 0,1 / 2 = 0,2 / 2 = 1,3 / 2 = 0等等。因此,对于每2个字符串字符,我们将值添加到1个数据字节
<强>湾(指数+ 1)%2 |我们希望奇数到1,甚至到0,因为十六进制字符串的第一个数字是最重要的,需要乘以16.所以对于索引0 =&gt; 0 + 1%2 = 1,索引1 =&gt; 1 + 1%2 = 0等。
<强>℃。 &LT;&LT; 4 | Shift by 4乘以16.示例:b00000001&lt;&lt; 4 = b00010000
答案 4 :(得分:3)
通过user411313的代码进行一些修改,以下内容适用于我:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main ()
{
char *hexstring = "deadbeef10203040b00b1e50";
int i;
unsigned int bytearray[12];
uint8_t str_len = strlen(hexstring);
for (i = 0; i < (str_len / 2); i++) {
sscanf(hexstring + 2*i, "%02x", &bytearray[i]);
printf("bytearray %d: %02x\n", i, bytearray[i]);
}
return 0;
}
答案 5 :(得分:3)
Michael Foukarakis的一个充实版本的帖子(因为我没有&#34;声誉&#34;对该帖子添加评论):
#include <stdio.h>
#include <string.h>
void print(unsigned char *byte_array, int byte_array_size)
{
int i = 0;
printf("0x");
for(; i < byte_array_size; i++)
{
printf("%02x", byte_array[i]);
}
printf("\n");
}
int convert(const char *hex_str, unsigned char *byte_array, int byte_array_max)
{
int hex_str_len = strlen(hex_str);
int i = 0, j = 0;
// The output array size is half the hex_str length (rounded up)
int byte_array_size = (hex_str_len+1)/2;
if (byte_array_size > byte_array_max)
{
// Too big for the output array
return -1;
}
if (hex_str_len % 2 == 1)
{
// hex_str is an odd length, so assume an implicit "0" prefix
if (sscanf(&(hex_str[0]), "%1hhx", &(byte_array[0])) != 1)
{
return -1;
}
i = j = 1;
}
for (; i < hex_str_len; i+=2, j++)
{
if (sscanf(&(hex_str[i]), "%2hhx", &(byte_array[j])) != 1)
{
return -1;
}
}
return byte_array_size;
}
void main()
{
char *examples[] = { "", "5", "D", "5D", "5Df", "deadbeef10203040b00b1e50", "02invalid55" };
unsigned char byte_array[128];
int i = 0;
for (; i < sizeof(examples)/sizeof(char *); i++)
{
int size = convert(examples[i], byte_array, 128);
if (size < 0)
{
printf("Failed to convert '%s'\n", examples[i]);
}
else if (size == 0)
{
printf("Nothing to convert for '%s'\n", examples[i]);
}
else
{
print(byte_array, size);
}
}
}
答案 6 :(得分:2)
hextools.h
#ifndef HEX_TOOLS_H
#define HEX_TOOLS_H
char *bin2hex(unsigned char*, int);
unsigned char *hex2bin(const char*);
#endif // HEX_TOOLS_H
hextools.c
#include <stdlib.h>
char *bin2hex(unsigned char *p, int len)
{
char *hex = malloc(((2*len) + 1));
char *r = hex;
while(len && p)
{
(*r) = ((*p) & 0xF0) >> 4;
(*r) = ((*r) <= 9 ? '0' + (*r) : 'A' - 10 + (*r));
r++;
(*r) = ((*p) & 0x0F);
(*r) = ((*r) <= 9 ? '0' + (*r) : 'A' - 10 + (*r));
r++;
p++;
len--;
}
*r = '\0';
return hex;
}
unsigned char *hex2bin(const char *str)
{
int len, h;
unsigned char *result, *err, *p, c;
err = malloc(1);
*err = 0;
if (!str)
return err;
if (!*str)
return err;
len = 0;
p = (unsigned char*) str;
while (*p++)
len++;
result = malloc((len/2)+1);
h = !(len%2) * 4;
p = result;
*p = 0;
c = *str;
while(c)
{
if(('0' <= c) && (c <= '9'))
*p += (c - '0') << h;
else if(('A' <= c) && (c <= 'F'))
*p += (c - 'A' + 10) << h;
else if(('a' <= c) && (c <= 'f'))
*p += (c - 'a' + 10) << h;
else
return err;
str++;
c = *str;
if (h)
h = 0;
else
{
h = 4;
p++;
*p = 0;
}
}
return result;
}
的main.c
#include <stdio.h>
#include "hextools.h"
int main(void)
{
unsigned char s[] = { 0xa0, 0xf9, 0xc3, 0xde, 0x44 };
char *hex = bin2hex(s, sizeof s);
puts(hex);
unsigned char *bin;
bin = hex2bin(hex);
puts(bin2hex(bin, 5));
size_t k;
for(k=0; k<5; k++)
printf("%02X", bin[k]);
putchar('\n');
return 0;
}
答案 7 :(得分:1)
char *hexstring = "deadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
while( *pos )
{
if( !((pos-hexstring)&1) )
sscanf(pos,"%02x",&val[(pos-hexstring)>>1]);
++pos;
}
sizeof(val)/ sizeof(val [0])是多余的!
答案 8 :(得分:1)
In main()
{
printf("enter string :\n");
fgets(buf, 200, stdin);
unsigned char str_len = strlen(buf);
k=0;
unsigned char bytearray[100];
for(j=0;j<str_len-1;j=j+2)
{ bytearray[k++]=converttohex(&buffer[j]);
printf(" %02X",bytearray[k-1]);
}
}
Use this
int converttohex(char * val)
{
unsigned char temp = toupper(*val);
unsigned char fin=0;
if(temp>64)
temp=10+(temp-65);
else
temp=temp-48;
fin=(temp<<4)&0xf0;
temp = toupper(*(val+1));
if(temp>64)
temp=10+(temp-65);
else
temp=temp-48;
fin=fin|(temp & 0x0f);
return fin;
}
答案 9 :(得分:1)
这是一个类似问题的修改函数,根据https://stackoverflow.com/a/18267932/700597的建议修改。
此函数将转换十六进制字符串 - 不以“0x”为前缀 - 使用偶数个字符转换为指定的字节数。如果遇到无效字符,或者十六进制字符串的长度为奇数,则返回-1,成功时返回0。
//convert hexstring to len bytes of data
//returns 0 on success, -1 on error
//data is a buffer of at least len bytes
//hexstring is upper or lower case hexadecimal, NOT prepended with "0x"
int hex2data(unsigned char *data, const unsigned char *hexstring, unsigned int len)
{
unsigned const char *pos = hexstring;
char *endptr;
size_t count = 0;
if ((hexstring[0] == '\0') || (strlen(hexstring) % 2)) {
//hexstring contains no data
//or hexstring has an odd length
return -1;
}
for(count = 0; count < len; count++) {
char buf[5] = {'0', 'x', pos[0], pos[1], 0};
data[count] = strtol(buf, &endptr, 0);
pos += 2 * sizeof(char);
if (endptr[0] != '\0') {
//non-hexadecimal character encountered
return -1;
}
}
return 0;
}
答案 10 :(得分:1)
这里是HexToBin和BinToHex相对干净和可读。 (注意最初通过错误记录系统返回的枚举错误代码不是简单的-1或-2。)
typedef unsigned char ByteData;
ByteData HexChar (char c)
{
if ('0' <= c && c <= '9') return (ByteData)(c - '0');
if ('A' <= c && c <= 'F') return (ByteData)(c - 'A' + 10);
if ('a' <= c && c <= 'f') return (ByteData)(c - 'a' + 10);
return (ByteData)(-1);
}
ssize_t HexToBin (const char* s, ByteData * buff, ssize_t length)
{
ssize_t result = 0;
if (!s || !buff || length <= 0) return -2;
while (*s)
{
ByteData nib1 = HexChar(*s++);
if ((signed)nib1 < 0) return -3;
ByteData nib2 = HexChar(*s++);
if ((signed)nib2 < 0) return -4;
ByteData bin = (nib1 << 4) + nib2;
if (length-- <= 0) return -5;
*buff++ = bin;
++result;
}
return result;
}
void BinToHex (const ByteData * buff, ssize_t length, char * output, ssize_t outLength)
{
char binHex[] = "0123456789ABCDEF";
if (!output || outLength < 4) return (void)(-6);
*output = '\0';
if (!buff || length <= 0 || outLength <= 2 * length)
{
memcpy(output, "ERR", 4);
return (void)(-7);
}
for (; length > 0; --length, outLength -= 2)
{
ByteData byte = *buff++;
*output++ = binHex[(byte >> 4) & 0x0F];
*output++ = binHex[byte & 0x0F];
}
if (outLength-- <= 0) return (void)(-8);
*output++ = '\0';
}
答案 11 :(得分:1)
以下是我出于性能原因写的解决方案:
void hex2bin(const char* in, size_t len, unsigned char* out) {
static const unsigned char TBL[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 58, 59, 60, 61,
62, 63, 64, 10, 11, 12, 13, 14, 15, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 10, 11, 12, 13, 14, 15
};
static const unsigned char *LOOKUP = TBL - 48;
const char* end = in + len;
while(in < end) *(out++) = LOOKUP[*(in++)] << 4 | LOOKUP[*(in++)];
}
示例:
unsigned char seckey[32];
hex2bin("351aaaec0070d13d350afae2bc43b68c7e590268889869dde489f2f7988f3fee", 64, seckey);
/*
seckey = {
53, 26, 170, 236, 0, 112, 209, 61, 53, 10, 250, 226, 188, 67, 182, 140,
126, 89, 2, 104, 136, 152, 105, 221, 228, 137, 242, 247, 152, 143, 63, 238
};
*/
如果您不需要支持小写:
static const unsigned char TBL[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 58, 59,
60, 61, 62, 63, 64, 10, 11, 12, 13, 14, 15
};
答案 12 :(得分:0)
你可以使用这个功能
scanf
、strtol
或 dynamic memory allocation
/// in: valid chars are 0-9 + A-F + a-f
/// out_len_max==0: convert until the end of input string, out_len_max>0 only convert this many numbers
/// returns actual out size
int hexStr2Arr(unsigned char* out, const char* in, size_t out_len_max = 0)
{
if (!out_len_max)
out_len_max = 2147483647; // INT_MAX
const int in_len = strnlen(in, out_len_max * 2);
if (in_len % 2 != 0)
return -1; // error, in str len should be even
// calc actual out len
const int out_len = out_len_max < (in_len / 2) ? out_len_max : (in_len / 2);
for (int i = 0; i < out_len; i++) {
char ch0 = in[2 * i];
char ch1 = in[2 * i + 1];
uint8_t nib0 = (ch0 & 0xF) + (ch0 >> 6) | ((ch0 >> 3) & 0x8);
uint8_t nib1 = (ch1 & 0xF) + (ch1 >> 6) | ((ch1 >> 3) & 0x8);
out[i] = (nib0 << 4) | nib1;
}
return out_len;
}
用法:
unsigned char result[128];
memset(result, 0, 128); // optional
printf("result len=%d\n", hexStr2Arr(result, "0a0B10")); // result = [0A 0B 10 00 00 ...]
memset(result, 0, 128); // optional
// only convert single number
printf("result len=%d\n", hexStr2Arr(result, "0a0B10", 1)); // result = [0A 00 00 00 00 ...]
答案 13 :(得分:0)
没有。但是在循环中使用sscanf
是相对微不足道的。
答案 14 :(得分:0)
这是一种处理文件的解决方案,它可能会更频繁地使用...
int convert(char *infile, char *outfile) {
char *source = NULL;
FILE *fp = fopen(infile, "r");
long bufsize;
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
int sourceLen = bufsize - 1;
int destLen = sourceLen/2;
unsigned char* dest = malloc(destLen);
short i;
unsigned char highByte, lowByte;
for (i = 0; i < sourceLen; i += 2)
{
highByte = toupper(source[i]);
lowByte = toupper(source[i + 1]);
if (highByte > 0x39)
highByte -= 0x37;
else
highByte -= 0x30;
if (lowByte > 0x39)
lowByte -= 0x37;
else
lowByte -= 0x30;
dest[i / 2] = (highByte << 4) | lowByte;
}
FILE *fop = fopen(outfile, "w");
if (fop == NULL) return 1;
fwrite(dest, 1, destLen, fop);
fclose(fop);
free(source);
free(dest);
return 0;
}
答案 15 :(得分:0)
使用strchr()的两个短程序来解析字节或单词。
// HexConverter.h
#ifndef HEXCONVERTER_H
#define HEXCONVERTER_H
unsigned int hexToByte (const char *hexString);
unsigned int hexToWord (const char *hexString);
#endif
// HexConverter.c
#include <string.h> // for strchr()
#include <ctype.h> // for toupper()
unsigned int hexToByte (const char *hexString)
{
unsigned int value;
const char *hexDigits = "0123456789ABCDEF";
value = 0;
if (hexString != NULL)
{
char *ptr;
ptr = strchr (hexDigits, toupper(hexString[0]));
if (ptr != NULL)
{
value = (ptr - hexDigits) << 4;
ptr = strchr (hexDigits, toupper(hexString[1]));
if (ptr != NULL)
{
value = value | (ptr - hexDigits);
}
}
}
return value;
}
unsigned int hexToWord (const char *hexString)
{
unsigned int value;
value = 0;
if (hexString != NULL)
{
value = (hexToByte (&hexString[0]) << 8) |
(hexToByte (&hexString[2]));
}
return value;
}
// HexConverterTest.c
#include <stdio.h>
#include "HexConverter.h"
int main (int argc, char **argv)
{
(void)argc; // not used
(void)argv; // not used
unsigned int value;
char *hexString;
hexString = "2a";
value = hexToByte (hexString);
printf ("%s == %x (%u)\n", hexString, value, value);
hexString = "1234";
value = hexToWord (hexString);
printf ("%s == %x (%u)\n", hexString, value, value);
hexString = "0102030405060708090a10ff";
printf ("Hex String: %s\n", hexString);
for (unsigned int idx = 0; idx < strlen(hexString); idx += 2)
{
value = hexToByte (&hexString[idx]);
printf ("%c%c == %x (%u)\n", hexString[idx], hexString[idx+1],
value, value);
}
return EXIT_SUCCESS;
}
答案 16 :(得分:0)
我所知道的最好方式:
int hex2bin_by_zibri(char *source_str, char *dest_buffer)
{
char *line = source_str;
char *data = line;
int offset;
int read_byte;
int data_len = 0;
while (sscanf(data, " %02x%n", &read_byte, &offset) == 1) {
dest_buffer[data_len++] = read_byte;
data += offset;
}
return data_len;
}
该函数返回保存在dest_buffer中的已转换字节数。 输入的字符串可以包含空格和大小写混合的字母。
“ 01 02 03 04 ab Cd eF垃圾AB”
转换为dest_buffer包含 01 02 03 04 ab cd ef
以及 “ 01020304abCdeFgarbageAB”
像以前一样翻译。
解析在第一个“错误”处停止。
答案 17 :(得分:0)
可能更简单吗?!
uint8_t hex(char ch) {
uint8_t r = (ch > 57) ? (ch - 55) : (ch - 48);
return r & 0x0F;
}
int to_byte_array(const char *in, size_t in_size, uint8_t *out) {
int count = 0;
if (in_size % 2) {
while (*in && out) {
*out = hex(*in++);
if (!*in)
return count;
*out = (*out << 4) | hex(*in++);
*out++;
count++;
}
return count;
} else {
while (*in && out) {
*out++ = (hex(*in++) << 4) | hex(*in++);
count++;
}
return count;
}
}
int main() {
char hex_in[] = "deadbeef10203040b00b1e50";
uint8_t out[32];
int res = to_byte_array(hex_in, sizeof(hex_in) - 1, out);
for (size_t i = 0; i < res; i++)
printf("%02x ", out[i]);
printf("\n");
system("pause");
return 0;
}
答案 18 :(得分:0)
这是我的版本:
/* Convert a hex char digit to its integer value. */
int hexDigitToInt(char digit) {
digit = tolower(digit);
if ('0' <= digit && digit <= '9') //if it's decimal
return (int)(digit - '0');
else if ('a' <= digit && digit <= 'f') //if it's abcdef
return (int)(digit - ('a' - 10));
else
return -1; //value not in [0-9][a-f] range
}
/* Decode a hex string. */
char *decodeHexString(const char *hexStr) {
char* decoded = malloc(strlen(hexStr)/2+1);
char* hexStrPtr = (char *)hexStr;
char* decodedPtr = decoded;
while (*hexStrPtr != '\0') { /* Step through hexStr, two chars at a time. */
*decodedPtr = 16 * hexDigitToInt(*hexStrPtr) + hexDigitToInt(*(hexStrPtr+1));
hexStrPtr += 2;
decodedPtr++;
}
*decodedPtr = '\0'; /* final null char */
return decoded;
}
答案 19 :(得分:0)
请尝试以下代码:
static unsigned char ascii2byte(char *val)
{
unsigned char temp = *val;
if(temp > 0x60) temp -= 39; // convert chars a-f
temp -= 48; // convert chars 0-9
temp *= 16;
temp += *(val+1);
if(*(val+1) > 0x60) temp -= 39; // convert chars a-f
temp -= 48; // convert chars 0-9
return temp;
}