Skip to content

Instantly share code, notes, and snippets.

@BohuTANG
Last active December 19, 2015 07:09
Show Gist options
  • Save BohuTANG/5916727 to your computer and use it in GitHub Desktop.
Save BohuTANG/5916727 to your computer and use it in GitHub Desktop.
Fixed: from buffer to uint64_t with big-endian sign extension bug
/*
* Such as num is:12345678910, 'from_big1' funcation will be wrong
* since the sign extension: 'cltq' instruction will full fill upper 32 bits with 0xffffffff
*/
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
void to_big(unsigned char *buf, uint64_t v)
{
buf[0] = (v >> 56) & 0xff;
buf[1] = (v >> 48) & 0xff;
buf[2] = (v >> 40) & 0xff;
buf[3] = (v >> 32) & 0xff;
buf[4] = (v >> 24) & 0xff;
buf[5] = (v >> 16) & 0xff;
buf[6] = (v >> 8) & 0xff;
buf[7] = v & 0xff;
}
uint64_t from_big1(unsigned char *buf)
{
uint64_t val = 0;
val |= (uint64_t) buf[0] << 56;
val |= (uint64_t) buf[1] << 48;
val |= (uint64_t) buf[2] << 40;
val |= (uint64_t) buf[3] << 32;
val |= buf[4] << 24;
val |= buf[5] << 16;
val |= buf[6] << 8;
val |= buf[7];
return val;
}
/*
* this is OK
*/
uint64_t from_big2(unsigned char *buf)
{
uint64_t val = 0;
val = buf[0];
val = (val<<8) | buf[1];
val = (val<<8) | buf[2];
val = (val<<8) | buf[3];
val = (val<<8) | buf[4];
val = (val<<8) | buf[5];
val = (val<<8) | buf[6];
val = (val<<8) | buf[7];
return val;
}
/*
* this is OK
*/
uint64_t from_big3(unsigned char *buf)
{
uint64_t val = 0;
val |= (uint64_t) buf[0] << 56;
val |= (uint64_t) buf[1] << 48;
val |= (uint64_t) buf[2] << 40;
val |= (uint64_t) buf[3] << 32;
val |= (uint64_t) buf[4] << 24;
val |= (uint64_t) buf[5] << 16;
val |= (uint64_t) buf[6] << 8;
val |= (uint64_t) buf[7];
return val;
}
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("./xx [num] [method:1 or 2]");
return -1;
}
uint64_t v1, v2;
unsigned char xx[8];
int method = atoi(argv[2]);
v1 = strtoull(argv[1], NULL, 0);
to_big(xx, v1);
switch (method) {
case 1:
v2 = from_big1(xx);
break;
case 2:
v2 = from_big2(xx);
break;
case 3:
v2 = from_big3(xx);
break;
default:break;
}
printf("v2 is %" PRIu64 "\n", v2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment