1

Suppose I have these variables,

const uint8_t ndef_default_msg[33] = {
    0xd1, 0x02, 0x1c, 0x53, 0x70, 0x91, 0x01, 0x09,
    0x54, 0x02, 0x65, 0x6e, 0x4c, 0x69, 0x62, 0x6e,
    0x66, 0x63, 0x51, 0x01, 0x0b, 0x55, 0x03, 0x6c,
    0x69, 0x62, 0x6e, 0x66, 0x63, 0x2e, 0x6f, 0x72,
    0x67
};
uint8_t *ndef_msg;
char *ndef_input = NULL;

How can I convert ndef_input (which is just a plain text, like "hello") to hex and save into ndef_msg? As you can see ndef_default_msg is in hex form. Data inside ndef_msg should be something like that as well.

A bit of background, in the original program (source code), the program will open a file, get the data and put it inside ndef_msg, which then will be written into a card. But I don't understand how it can take the data and convert to hex.

I want to simplify the program so it will directly ask user for text (instead of asking for a file).

bitmask
  • 32,434
  • 14
  • 99
  • 159
Tyron Maples
  • 35
  • 1
  • 2
  • 6
  • Are you looking to take user input into `ndef_input` and save the ascii values of the characters entered into `ndef_msg`, or am I misunderstanding you? Or is the user supposed to enter actual hex values? – Dervall Feb 22 '12 at 14:03
  • 3
    You DO know that data is stored in binary inside the memory and you already HAVE the hex "versions" of every char the user entered? – Eregrith Feb 22 '12 at 14:07
  • @Dervall, indeed that's what I'm planning to do. user will just key in simple text like "hello", then the program has to convert to hex value of "hello". – Tyron Maples Feb 22 '12 at 14:35
  • @Eregrith, I don't have the hex version of user's input. Indeed data will be stored in binary form inside the card, but that's the job of library/API. My concern is getting the hex version of user's input. – Tyron Maples Feb 22 '12 at 14:38
  • What card? What's "the hex version of user's input"? User will enter characters, these will be stored inside bytes of memory one at a time (your `ndef_input` I presume). From here you have two choices : use each byte _as is_ because any way it's already "converted", or parse the whole input as a giant number in a hex form ("0109400AFED092DEF" for example) so you will need scanf() as answered by [Ade YU](http://stackoverflow.com/users/990825/ade-yu) – Eregrith Feb 22 '12 at 15:12
  • @Eregrith, nfc card, that's why ndef is there, it's the NFC Forum data format. I think I can use the first choice. because inside the source code (refer to the link provided), `ndef_stream` (in line 160) suppose to pass value to `ndef_msg` but I can't see any conversion done or passing. I can't see because I'm not familiar with file io. what would happen in first choice? – Tyron Maples Feb 22 '12 at 15:26
  • You would just have to go through `ndef_input` and put it (casted to `uint8_t`) into `ndef_msg`. This for example will take a ndef_input like `"abc"` and transfer it to ndef_msg as `{ 0x61, 0x62, 0x63 }` (ascii hex values of a, b and c). – Eregrith Feb 22 '12 at 16:12

5 Answers5

6

Why not read it into ndef_msg directly, (minus the \0 if it suppose to be a pure array). The hex are just for presentation, you could have just picked decimal or octal with no consequence for the content.

void print_hex(uint8_t *s, size_t len) {
    for(int i = 0; i < len; i++) {
        printf("0x%02x, ", s[i]);
    }
    printf("\n");
}

int main()
{
    uint8_t ndef_msg[34] = {0};

    scanf("%33s", ndef_msg);
    print_hex(ndef_msg, strlen((char*)ndef_msg));


    return 0;
}

You probably need to handle the reading of the string differently to allow for whitespace and perhaps ignore \0, this is just to illustrate my point.

foo
  • 387
  • 2
  • 9
  • meaning user's character input pass directly to `ndef_msg`? possible? how can I do that? – Tyron Maples Feb 22 '12 at 15:37
  • Presumably, you have space allocated to hold the characters since in your case ndef_msg is only a pointer. Or I have misunderstood what it is you are trying to do. What I'm trying to say is that the only thing that differs is the sign of your type, no conversion to hex is necessary. – foo Feb 22 '12 at 15:40
  • I see. that's why I don't see hex conversion done in original program. I'll try your solution as well. Thanks. – Tyron Maples Feb 22 '12 at 15:54
  • This might help: http://www.asciitable.com/ if ndef_msg in not a string you might have to read one character at a time and stop at max_lengt (33) or `\n`. – foo Feb 22 '12 at 15:58
0
char *ndef_input="Z";

uint8_t b=90; //assume this is your character Z in decimal ascii code 90 and HEX = 5A
uint8_t LSB = b & 0x0F; // this is LSB 10 decimal = A
uint8_t MSB = (b & 0xF0)>>4; // this is MSB 5 in decimal = 5 in Hex
cout << "MSB" << MSB << "LSB" << LSB;
Sherif O.
  • 506
  • 4
  • 15
0

If I understand right, you read data of hex format stored in ndef_input, parse it and save the value in ndef_msg.

you may use

// parse the hex string and store it in an int variable
int temp_int;
sscanf(ndef_input, "%x", &temp_int);
// covert it to uint8_t type
ndef_msg = malloc(sizeof(uint8_t));
*ndef_msg = (uint8_t)temp_int;
jørgensen
  • 10,149
  • 2
  • 20
  • 27
Ade YU
  • 2,292
  • 3
  • 18
  • 28
  • oh, `sscanf`, I've been trying `sprintf` which resulted in crash. But I thought `new` is C++ ? Shall I cast `temp_int` instead (to be in `uint8_t` type)? – Tyron Maples Feb 22 '12 at 14:50
  • @TyronMaples Yes, in C, it should have been `malloc(sizeof(uint8_t))`. And yes. `*ndef_msg = (uint8_t)temp_int;` – Ade YU Feb 22 '12 at 14:58
  • thanks for the clarification. one question, due to error checking, the conversion will be done inside a `if else` statement, so if I put `int temp_int;` inside `if else`, `ndef_msg` will have empty data after `if else` because `temp_int` has been destroyed, isn't it? – Tyron Maples Feb 22 '12 at 15:08
  • one more thing, do I need `free` because `malloc` is used? if it does, what shall I `free` and where do I put it? – Tyron Maples Feb 22 '12 at 15:12
  • @TyronMaples No. `temp_int` will go out of scope after the `if else` block. But what `ndef_msg` points to keeps the value until you `free` it. – Ade YU Feb 22 '12 at 15:15
  • @TyronMaples `free(ndef_msg);` when you do not need it any longer. – Ade YU Feb 22 '12 at 15:17
0

Maybe not very elegant but simple: define a look up table that maps a character code (0 to 255) into a desired value.

// something like this:
for( i = 0; i < INPUT_LEN; ++i ) {
    value_in = input[i];
    value_out = lut[value_in];
    array_out[i] = value_out;
}

I used such not-elegant solutions a couple of times (e.g. for color mapping) and it worked equally good as other fancy solutions

Jakub M.
  • 32,471
  • 48
  • 110
  • 179
-1

I hope that can help you

/*
 *  DESCRIPTION
 *    Converts a block in ASCII representation to binary
 *  PARAMETERS
 *    char * inMessage      : message in ASCII format, '\0' terminated
 *  OUTPUTS
 *    uint8 * outMessage    : output message in binary format
 *                    Format: outMessage[i], where i is byte number
 *  RETURN VALUE
 *    uint32                : number of converted bytes
 */
uint32 ascii2hex_block( uint8 * outMessage, int32 out_len, const char * inMessage )
{
    #define SET_BIT(U,N)   ((U) |=   (0x1 << (N)))

    int32   i = 0;
    int32   k = 0;
    int32   blockLen = 0;
    char    inChar;
    uint8   hexVal;
    uint32  retVal = 0;

    while ( inMessage[blockLen]!='\0' )     blockLen++;
    blockLen = blockLen >> 1;

    if (blockLen <= out_len)                        // not enough space in output
    {
        retVal = blockLen;
        for (i = 0; i < blockLen; i++)
        {
            outMessage[i] = 0;
            inChar = inMessage[k];
            hexVal = ascii2hex( inChar );
            if (hexVal == 0xff) retVal = 0;     // found an invalid character
            if ( (hexVal & (0x1 << 0) ) != 0 )  SET_BIT( outMessage[i], 4 );
            if ( (hexVal & (0x1 << 1) ) != 0 )  SET_BIT( outMessage[i], 5 );
            if ( (hexVal & (0x1 << 2) ) != 0 )  SET_BIT( outMessage[i], 6 );
            if ( (hexVal & (0x1 << 3) ) != 0 )  HELPER_SET_BIT( outMessage[i], 7 );
            k++;
            inChar = inMessage[k];
            hexVal = ascii2hex( inChar );
            if ( (hexVal & (0x1 << 0) ) != 0 )  SET_BIT( outMessage[i], 0 );
            if ( (hexVal & (0x1 << 1) ) != 0 )  SET_BIT( outMessage[i], 1 );
            if ( (hexVal & (0x1 << 2) ) != 0 )  SET_BIT( outMessage[i], 2 );
            if ( (hexVal & (0x1 << 3) ) != 0 )  SET_BIT( outMessage[i], 3 );
            k++;
        }
    }   

    return retVal;
}

And ascii2hex is defined as follow:

/*
 *  DESCRIPTION
 *    Converts an ascii character ('0'..'f' or '0'..'F') to corresponding integer value.
 *    In case of invalid ascii character, return value is 0xff
 *  USAGE
 *    uint8 ascii2hex( char inASCII );
 *  PARAMETERS
 *    char inASCII  : ascii character to convert
 *  RETURN VALUE
 *    uint8         : value of inASCII, 0xff for invalid input
 */
uint8 ascii2hex( char inASCII )
{
    uint8 retHex=0xff;

    if( (inASCII>=48) && (inASCII<=57) )
        retHex = inASCII-48;
    else if( (inASCII>=65) && (inASCII<=70) )
        retHex = inASCII-55;
    else if( (inASCII>=97) && (inASCII<=102) )
        retHex = inASCII-87;

    return retHex;
}
lucaboni
  • 2,334
  • 2
  • 29
  • 41