Click here to Skip to main content
15,886,422 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi All,

I am trying to display a hexa decimal value with length ranging from (40 digits to 60 digits)
as a result of SHA1HMAC algorithm. I have to display that hexa number in the format of 4 digits and after that a space (eg: 0x1234 5678 90AB CDEF ....)

I am using the below code but i am getting an error saying

"Run-Time Check Failure #2 - Stack around the variable 'formatString' was corrupted."


Please let me know how to handle this scenario and fix this. It would be great if I dynamically format because the length of the hexa decimal number may vary(from 40 digits to 60 digits)

Appreciate your help.

Thanks,
Sudhakar

code:

C++
#ifdef _MSC_VER 
inline unsigned __int64 strtoull(const char *nptr, char **endptr, int base)
{ return _strtoui64(nptr, endptr, base); }
#endif

GDString result = "123456789ABCDEF123456789ABCDEF123456789"
GDUINT64 value = strtoull(result.c_str(),NULL,16 )  ;

GDString resultString;
char formatString[50] = {0};
		
sprintf(formatString,"0x%04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X",
			(unsigned)(value >> 160ULL) & 0xFFFF, 
			(unsigned)(value >> 144ULL) & 0xFFFF, 
			(unsigned)(value >> 128ULL) & 0xFFFF, 
			(unsigned)(value >> 112ULL) & 0xFFFF, 
			(unsigned)(value >> 96ULL) & 0xFFFF, 
			(unsigned)(value >> 80ULL) & 0xFFFF, 
			(unsigned)(value >> 64ULL) & 0xFFFF, 
			(unsigned)(value >> 48ULL) & 0xFFFF, 
			(unsigned)(value >> 32ULL) & 0xFFFF, 
			(unsigned)(value >> 16) & 0xFFFF, 
			(unsigned)value & 0xFFFF);

		resultString = formatString;
Posted
Comments
nv3 7-Mar-14 16:51pm    
How do you expect to 11 * 4 = 44 hex digits into a 64 bit uint value? There are no more than 16 hex digits in a 64 bit value. Besides that solution 2 is a good start for what you want to do.
merano 7-Mar-14 18:11pm    
You are right, something is wrong with the shift. But your comment does not catch the facts.

He tries to shift 176 Bits, converted to hex-text into a 50 char output buffer.

Both datatypes are to small for this action. See Solution 3.

value: 11 * 2 * 8 Bit = 176 Bit

formatString: 2 + 44 + 10 + 1 = 57 chars

The shift is strange and the buffer to small.
nv3 7-Mar-14 18:28pm    
Yes, formatString is too short to receive the 57 character result of the printf. Nevertheless, his variable "value" is of type _int64 and hence cannot hold 176 bits in the first place.

C++
static const char lookup[] = "0123456789ABCDEF";

// value to be printed.
long long work = value;
// text output
char text[32] = {0}; // should be 21 chars max.
size_t len = (sizeof text) - 1;
do
{
    // display least significant 16 bits.
    text[--len] = lookup[work & 0xF];
    // shift down for next nibble.
    work >>= 4;
    text[--len] = lookup[work & 0xF];
    // shift down for next nibble.
    work >>= 4;
    text[--len] = lookup[work & 0xF];
    // shift down for next nibble.
    work >>= 4;
    text[--len] = lookup[work & 0xF];
    // shift down for next nibble.
    work >>= 4;
    // any non-zero bits left?
    if (work == 0)
    {
        // no: hex prefix.
        text[--len] = 'x';
        text[--len] = '0';
    }
    else
    {
        text[--len] = ' ';
    }
}
while (work);
// output is at &text[len].
fprintf(stdout, "%s", text + len);
 
Share this answer
 
v2
formatString at 50 chars is not big enough for the result in the snippet you posted, you'll need at least 57 if I'm not mistaken.
0x = 2
11 groups of 4 digits = 44
10 spaces = 10
null terminator = 1
 
Share this answer
 
Comments
merano 7-Mar-14 17:59pm    
You need at least 57 chars for output buffer, but before that you need

11 * 2 * 8 Bit = 176 Bit datatype for value, but i think there are only 64 Bit.

The shift is strange.
jeron1 7-Mar-14 18:09pm    
Yeah, I wasn't really looking at the logic or datatypes, merely the usage of formatString.
Member 3975629 10-Mar-14 4:23am    
Thanks for your solution. it seems working on windows fine. but on Linux it is giving the below error with the same above code though i have used unsignd long long as the data type for value .Please let me know if you have any idea/suggetion on this.

error: right shift count >= width of type

And also please let me know how to avoid hard coding of here with shifts. I mean here i used 11 groups of 4 digits by using >> operator. but is there any way that we can dynamically get the format string with different length of value ? and also what could be the max value of a int64 value ? i mean how many max digits can it have ?

Appreciate your help.

Thanks,
Sudhakar
There is no need to convert the string into numbers. Just print out the string portions inserting spaces at the required positions:
const char *sha1 = "123456789ABCDEF123456789ABCDEF123456789";

printf("In: %s\n", sha1);
printf("Out: 0x");
size_t len = strlen(sha1);
// Get number of digits for first part if not a multiple of 4.
size_t digits = len % 4;
if (digits == 0)
    digits = 4;
const char *src = sha1;
while (*src)
{
    if (src > sha1)
        printf(" ");
    for (size_t i = 0; i < digits; i++)
        printf("%c", *src++);
    digits = 4;
}
printf("\n");

If you need the output stored in a buffer use something similar:
size_t len = strlen(sha1);
char *buf = new char[len + 4 + len / 4];
const char *src = sha1;
char *dst = buf;
*dst++ = '0';
*dst++ = 'x';
// Get number of digits for first part if not a multiple of 4.
size_t digits = len % 4;
if (digits == 0)
    digits = 4;
while (*src)
{
    if (src > sha1)
        *dst++ = ' ';
    for (size_t i = 0; i < digits; i++)
        *dst++ = *src++;
    digits = 4;
}
*dst = '\0';
printf("In: %s\nOut: %s\n", sha1, buf);
delete [] buf
 
Share this answer
 
Comments
Member 3975629 10-Mar-14 10:50am    
Thanks a lot to all of you who tried to help me in answering the question.

Solution 4 is working fine. it is addressing my requirements.

Appreciate your help.

Thank you All,
Sudhakar
I'm not a C++ specialist, at all, so I won't be able to post any code, but, as far as I know, there is no pre-made format string that could display an hexadecimal value with every four-digits groups isolated.
Maybe you could break it down to several simple steps :
1) Build an hexadecimal string from the value
2) Create a custom method that will accept your hexadecimal string as input, and return it under the form of 4-digits groups. I could easily write that in C# or in VB, but not in C++; sorry :(

Hope this helps, anyway. Good luck!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900