gda2004
gda2004

Reputation: 746

MAC address parsing

I have a MAC address like "6F:e:5B:7C:b:a" that I want to parse and insert the implicit zeros before the :e:, :b:, :a.

I cannot use Boost at the moment but I have a rough solution. The solution splits on ':'. Then I count the characters between and if there is only one I insert a zero at the front.

I was wondering if anyone had a faster approach?

Upvotes: 0

Views: 4620

Answers (2)

Tin
Tin

Reputation: 21

For the quick and dirty:

if (sscanf(text, "%x:%x:%x:%x:%x:%x",
           &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) {
    // handle error
}

Note that it does not check if numbers are really hex. Usual precautions of sscanf() applies.

Upvotes: 2

Vyktor
Vyktor

Reputation: 20997

First of all you could use script that would convert char to int quite fast, so:

unsigned char hex_to_int(const char c)
{
    if( c >= 'a' && c <= 'f'){
        return c - 'a' + 10;
    }

    if( c >= 'A' && c <= 'F'){
        return c - 'A' + 10;
    }

    if( c >= '0' && c <= '9'){
        return c - '0';
    }

    return 0;
}

Then you may create loop that will iterate over the string:

unsigned char mac[6]; /* Resulting mac */
int i; /* Iteration number */
char *buffer; /* Text input - will be changed! */
unsigned char tmp; /* Iteration variable */

for( i = 0; i < 6; ++i){
    mac[i] = 0;

    /*
     * Next separator or end of string 
     * You may also want to limit this loop to just 2 iterations
     */
    while( ((*buffer) != '\0') && ((*buffer) != ':'){
        mac[i] <<= 4;
        mac[i] |= hex_to_int( *buffer);
        ++buffer;
    }
}

if( (i != 6) || (*buffer != NULL)){
    // Error in parsing, failed to get to the 6th iteration
    // or having trailing characters at the end of MAC
}

This function doesn't do any error checking, but it's probably the fastest solution you'll be getting.

Upvotes: 1

Related Questions