使用二进制字符串进行操作
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
int bin_to_dec(char* s) {
int i, N, decimal_number = 0, p = 0;
N = strlen(s);
for (i = N - 1; i >= 0; i--) {
if (s[i] == '1')
decimal_number += pow(2, p);
p++;
}
return decimal_number;
}
char* int2bin(int a, char* buffer, int padding) {
buffer += (padding - 1);
for (int i = padding-1; i >= 0; i--) {
*buffer-- = (a & 1) + '0';
a >>= 1;
}
return buffer;
}
int main(int argc, char* argv[]) {
const char* pos = strchr(argv[1], '/');
char strIp[16] = { 0 };
memcpy(strIp, argv[1], pos - argv[1]);
char strCidr[16] = { 0 };
memcpy(strCidr, pos + 1, strlen(argv[1]) - (pos - argv[1]) - 1);
printf("IP part: %s\n", strIp);
printf("Cidr part: %s\n", strCidr);
if (-1 == inet_addr(strIp)) {
printf("invalid IP format");
exit(-1);
}
// split to four parts
const char* firstDotPos = strchr(strIp, '.');
const char* secondDotPos = strchr(firstDotPos + 1, '.');
const char* thirdDotPos = strchr(secondDotPos + 1, '.');
char firstIpPart[16] = { 0 };
char secondIpPart[16] = { 0 };
char thirdIpPart[16] = { 0 };
char fourIpPart[16] = { 0 };
memcpy(firstIpPart, strIp, firstDotPos - strIp);
memcpy(secondIpPart, firstDotPos + 1, secondDotPos - firstDotPos - 1);
memcpy(thirdIpPart, secondDotPos + 1, thirdDotPos - secondDotPos - 1);
memcpy(fourIpPart, thirdDotPos + 1, strlen(strIp) - (thirdDotPos - strIp) - 1);
printf("\nfirst IP part: %s\n", firstIpPart);
printf("second IP part: %s\n", secondIpPart);
printf("third IP part: %s\n", thirdIpPart);
printf("fourth IP part: %s\n", fourIpPart);
// convert each part to binary string
char binFirstIpPart[16] = { 0 };
char binSecondIpPart[16] = { 0 };
char binThirdIpPart[16] = { 0 };
char binFourthIpPart[16] = { 0 };
int _1 = atoi(firstIpPart);
int _2 = atoi(secondIpPart);
int _3 = atoi(thirdIpPart);
int _4 = atoi(fourIpPart);
int2bin(_1, binFirstIpPart, 8);
int2bin(_2, binSecondIpPart, 8);
int2bin(_3, binThirdIpPart, 8);
int2bin(_4, binFourthIpPart, 8);
printf("\nfirst IP binary part: %s\n", binFirstIpPart);
printf("second IP binary part: %s\n", binSecondIpPart);
printf("third IP binary part: %s\n", binThirdIpPart);
printf("fourth IP binary part: %s\n", binFourthIpPart);
// combine these four part and convert to decimal
char strIpValue[34] = { 0 };
strcpy_s(strIpValue, binFirstIpPart);
strcat_s(strIpValue, binSecondIpPart);
strcat_s(strIpValue, binThirdIpPart);
strcat_s(strIpValue, binFourthIpPart);
printf("\nIP value string:\n\t%s\n", strIpValue);
// just use memcpy to get prefix and start part string is fine, you don't need to
// tranform it to decimal
char strPrefix[34] = { 0 };
memcpy(strPrefix, strIpValue, atoi(strCidr));
char strStart[34] = { 0 };
memcpy(strStart, strIpValue + atoi(strCidr), 32 - atoi(strCidr));
printf("\nafter split:\n\t%s / %s\n", strPrefix, strStart);
int start = bin_to_dec(strStart);
int end = pow(2, 32 - atoi(strCidr)) - 1;
printf("\nrange: %d~%d\n\n", start, end);
// print all IP in specify range
printf("\npress enter to continue\n");
getchar();
printf("calculated IP range:\n");
for (int i = start; i <= end; i++) {
char strRange[34] = { 0 };
int2bin(i, strRange, 32 - atoi(strCidr));
char strBinIp[34] = { 0 };
strcpy_s(strBinIp, strPrefix);
strcat_s(strBinIp, strRange);
memset(binFirstIpPart, 0, 16);
memset(binSecondIpPart, 0, 16);
memset(binThirdIpPart, 0, 16);
memset(binFourthIpPart, 0, 16);
memcpy(binFirstIpPart, strBinIp, 8);
memcpy(binSecondIpPart, strBinIp + 8, 8);
memcpy(binThirdIpPart, strBinIp + 8 + 8, 8);
memcpy(binFourthIpPart, strBinIp + 8 + 8 + 8, 8);
_1 = bin_to_dec(binFirstIpPart);
_2 = bin_to_dec(binSecondIpPart);
_3 = bin_to_dec(binThirdIpPart);
_4 = bin_to_dec(binFourthIpPart);
char strFinalIp[34];
sprintf_s(strFinalIp, "%d.%d.%d.%d\n", _1, _2, _3, _4);
// printf("%s\n", strBinIp);
printf("\t%s\n", strFinalIp);
}
return 0;
}
C:\Users\x\source\repos\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe 1.2.3.43/20