Reputation: 735
I want to convert a hex string such as "43a2be2a42380" to their decimal representation using a uint64 variable. I need that because i'm implementing a RFID reader acting as a keyboard and the keypresses need to be the decimal digit.
I have seen other answers (convert HEX string to Decimal in arduino) and implementing a solution using strtoul but it only works for 32 bit integers and strtoull is not available.
uint64_t res = 0;
String datatosend = String("43a2be2a42380");
char charBuf[datatosend.length() + 1];
datatosend.toCharArray(charBuf, datatosend.length() + 1) ;
res = strtoul(charBuf, NULL, 16);
What can i do to get the decimal number of a big hex string / byte array using an Arduino?
Upvotes: 4
Views: 4169
Reputation: 42849
You can make your own implementation :
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
uint64_t getUInt64fromHex(char const *str)
{
uint64_t accumulator = 0;
for (size_t i = 0 ; isxdigit((unsigned char)str[i]) ; ++i)
{
char c = str[i];
accumulator *= 16;
if (isdigit(c)) /* '0' .. '9'*/
accumulator += c - '0';
else if (isupper(c)) /* 'A' .. 'F'*/
accumulator += c - 'A' + 10;
else /* 'a' .. 'f'*/
accumulator += c - 'a' + 10;
}
return accumulator;
}
int main(void)
{
printf("%llu\n", (long long unsigned)getUInt64fromHex("43a2be2a42380"));
return 0;
}
Upvotes: 6
Reputation: 1019
And more shorter convert:
void str2hex(uint8_t * dst, uint8_t * str, uint16_t len)
{
uint8_t byte;
while (len) {
byte = *str-(uint8_t)0x30;
if (byte > (uint8_t)0x9) byte -= (uint8_t)0x7;
*dst = byte << 4;
str++;
byte = *str-(uint8_t)0x30;
if (byte > (uint8_t)0x9) byte -= (uint8_t)0x7;
*dst |= byte;
str++; dst++;
len -= (uint16_t)0x1;
}
}
And than for get uint64_t from unsigned char buffer:
uint64_t hex2_64(uint8_t * ptr)
{
uint64_t ret;
ret = (uint64_t)((uint64_t)(*ptr) << (uint64_t)56); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)48); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)40); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)32); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)24); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)16); ptr++;
ret |= (uint64_t)((uint64_t)(*ptr) << (uint64_t)8); ptr++;
ret |= (uint64_t)(*ptr);
return ret;
}
Upvotes: 0
Reputation: 70971
... solution using
strtoul
but it only works for 32 bit integers andstrtoull
is not available.
Do it twice using strtoul()
, once for the lower four bytes, once for the rest and add the two results, multiplying the latter by 0x100000000LLU
beforehand.
Upvotes: 6