h3ct0r
h3ct0r

Reputation: 735

Arduino: Convert hex string to uint64 or decimal string

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

Answers (3)

Boiethios
Boiethios

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

imbearr
imbearr

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

alk
alk

Reputation: 70971

... solution using strtoul but it only works for 32 bit integers and strtoull 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

Related Questions