C:将十六进制字符串解析为无符号长
C : Parse Hex string to unsigned long
我有一个带有 IP 地址的字符串:
char *input_string = "fe80000000000000022318fffeedef59";
我需要将其转换为无符号长整数:
unsigned long l = 0xfe80000000000000022318fffeedef59;
我尝试了一些代码,但是 none 有效,这是我做的:
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *input_string = "fe80000000000000022318fffeedef59";
printf("input_string : %s\n\n", input_string);
unsigned long l1 = strtol(input_string, NULL, 16);
printf("unsigned long l1 = strtol(input_string, NULL, 16) : l1 = %lx \n\n", l1);
unsigned long l2 = atol(input_string);
printf("unsigned long l2 = atol(input_string) : l2 = %lx \n\n", l2);
}
输出:
input_string : fe80000000000000022318fffeedef59
unsigned long l1 = strtol(input_string, NULL, 16) : l1 = 7fffffffffffffff
unsigned long l2 = atol(input_string) : l2 = 0
你的电话号码太大了。您应该检查函数 strtol 和 atol 的 return 状态。
您输入的字符串(32 字节)对应于一个非常大的十六进制数。为了保存这样一个 32 字节的字符串,您需要一个 16 字节(128 位)的数据类型。但是 unsigned long 只有 8 个字节。这就是您得到这样输出的原因。
这是我最终完成的。
#include <stdio.h>
#include <string.h>
void big_hex_string_to_long_array(char *);
void main( void)
{
char *ipv6_string = "FE800000000000000202B3FFFE1E8329";
big_hex_string_to_long_array(ipv6_string);
}
/*
* The ipv6 address is 128 bits long, too much to process in a single block.
* Here I split the address in four equals parts of 32 bits which can be stored
* in an long int (4 Bytes).
*/
void big_hex_string_to_long_array(char * hex_string)
{
// create two buffers, one for the most significants bytes and the other for the lowest significants bytes
char buf_1[8+1]; // +1 : the space for '[=10=]'
char buf_2[8+1];
char buf_3[8+1];
char buf_4[8+1];
// copy each half in each buffers and add ending character
memcpy(buf_1, &(*hex_string), sizeof(char)* 8); // copy the 8 first characters in buf_1
buf_1[8]='[=10=]'; // set the last character
memcpy(buf_2, &(*hex_string)+8, sizeof(char)* 8); // copy the 8 next characters in buf_2
buf_2[8]='[=10=]'; //...
memcpy(buf_3, &(*hex_string)+16, sizeof(char)* 8);
buf_3[8]='[=10=]';
memcpy(buf_4, &(*hex_string)+24, sizeof(char)* 8);
buf_4[8]='[=10=]';
printf("\nchar arrays : \nbuf1 = %s\nbuf2 = %s\nbuf3 = %s\nbuf4 = %s\n",buf_1, buf_2, buf_3, buf_4);
// store each buffer as unsigned long
long l1 = strtol(buf_1, NULL, 16); // convert string to long
long l2 = strtol(buf_2, NULL, 16);
long l3 = strtol(buf_3, NULL, 16);
long l4 = strtol(buf_4, NULL, 16);
printf("\nlong int : \nl1 = %lx\nl2 = %lx\nl3 = %lx\nl4 = %lx\n",l1, l2, l3, l4);
}
输出
char arrays :
buf1 = FE800000
buf2 = 00000000
buf3 = 0202B3FF
buf4 = FE1E8329
long int :
l1 = fffffffffe800000
l2 = 0
l3 = 202b3ff
l4 = fffffffffe1e8329
作为 @Weather Vane 评论:"You'll need a 128-bit numeric variable to hold the value from a 32-byte hex string"
可以使用sscanf()
保存成2个64位整数。
#include <stdio.h>
#include <stdint.h>
int main(void) {
uint64_t add[2];
char *input_string = "fe80000000000000022318fffeedef59";
if (2 != sscanf(input_string, "%16" SCNx64 "%16" SCNx64, &add[0], &add[1])) {
return -1;
}
printf("%016" PRIx64 "%016" PRIx64 , add[0], add[1]);
return 0;
}
我有一个带有 IP 地址的字符串:
char *input_string = "fe80000000000000022318fffeedef59";
我需要将其转换为无符号长整数:
unsigned long l = 0xfe80000000000000022318fffeedef59;
我尝试了一些代码,但是 none 有效,这是我做的:
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *input_string = "fe80000000000000022318fffeedef59";
printf("input_string : %s\n\n", input_string);
unsigned long l1 = strtol(input_string, NULL, 16);
printf("unsigned long l1 = strtol(input_string, NULL, 16) : l1 = %lx \n\n", l1);
unsigned long l2 = atol(input_string);
printf("unsigned long l2 = atol(input_string) : l2 = %lx \n\n", l2);
}
输出:
input_string : fe80000000000000022318fffeedef59
unsigned long l1 = strtol(input_string, NULL, 16) : l1 = 7fffffffffffffff
unsigned long l2 = atol(input_string) : l2 = 0
你的电话号码太大了。您应该检查函数 strtol 和 atol 的 return 状态。
您输入的字符串(32 字节)对应于一个非常大的十六进制数。为了保存这样一个 32 字节的字符串,您需要一个 16 字节(128 位)的数据类型。但是 unsigned long 只有 8 个字节。这就是您得到这样输出的原因。
这是我最终完成的。
#include <stdio.h>
#include <string.h>
void big_hex_string_to_long_array(char *);
void main( void)
{
char *ipv6_string = "FE800000000000000202B3FFFE1E8329";
big_hex_string_to_long_array(ipv6_string);
}
/*
* The ipv6 address is 128 bits long, too much to process in a single block.
* Here I split the address in four equals parts of 32 bits which can be stored
* in an long int (4 Bytes).
*/
void big_hex_string_to_long_array(char * hex_string)
{
// create two buffers, one for the most significants bytes and the other for the lowest significants bytes
char buf_1[8+1]; // +1 : the space for '[=10=]'
char buf_2[8+1];
char buf_3[8+1];
char buf_4[8+1];
// copy each half in each buffers and add ending character
memcpy(buf_1, &(*hex_string), sizeof(char)* 8); // copy the 8 first characters in buf_1
buf_1[8]='[=10=]'; // set the last character
memcpy(buf_2, &(*hex_string)+8, sizeof(char)* 8); // copy the 8 next characters in buf_2
buf_2[8]='[=10=]'; //...
memcpy(buf_3, &(*hex_string)+16, sizeof(char)* 8);
buf_3[8]='[=10=]';
memcpy(buf_4, &(*hex_string)+24, sizeof(char)* 8);
buf_4[8]='[=10=]';
printf("\nchar arrays : \nbuf1 = %s\nbuf2 = %s\nbuf3 = %s\nbuf4 = %s\n",buf_1, buf_2, buf_3, buf_4);
// store each buffer as unsigned long
long l1 = strtol(buf_1, NULL, 16); // convert string to long
long l2 = strtol(buf_2, NULL, 16);
long l3 = strtol(buf_3, NULL, 16);
long l4 = strtol(buf_4, NULL, 16);
printf("\nlong int : \nl1 = %lx\nl2 = %lx\nl3 = %lx\nl4 = %lx\n",l1, l2, l3, l4);
}
输出
char arrays :
buf1 = FE800000
buf2 = 00000000
buf3 = 0202B3FF
buf4 = FE1E8329
long int :
l1 = fffffffffe800000
l2 = 0
l3 = 202b3ff
l4 = fffffffffe1e8329
作为 @Weather Vane 评论:"You'll need a 128-bit numeric variable to hold the value from a 32-byte hex string"
可以使用sscanf()
保存成2个64位整数。
#include <stdio.h>
#include <stdint.h>
int main(void) {
uint64_t add[2];
char *input_string = "fe80000000000000022318fffeedef59";
if (2 != sscanf(input_string, "%16" SCNx64 "%16" SCNx64, &add[0], &add[1])) {
return -1;
}
printf("%016" PRIx64 "%016" PRIx64 , add[0], add[1]);
return 0;
}