OK , Tôi đã làm điều này trong C chứ không phải là C++, nhưng nó sẽ làm việc. Ngoài ra, nó sử dụng bswap_64 mà là AFAIK một phần mở rộng GNU vì vậy có thể không hoạt động trên tất cả mọi thứ.
Nó có vẻ là rất nhanh chóng trên amd64, và nhanh hơn so với giải pháp hiện tại Yasar đã đưa ra:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>
#if defined __GNUC__ && __GNUC__ >= 2
#include <byteswap.h>
#else
#error "Sorry, you need GNU for this"
#endif
struct split
{
uint64_t start;
uint64_t end;
};
void ipv6_prefix (unsigned char *masked, unsigned char *packed, int prefix)
{
struct split parts;
uint64_t mask = 0;
unsigned char *p = masked;
memset(masked, 0, sizeof(struct in6_addr));
memcpy(&parts, packed, sizeof(parts));
if (prefix <= 64)
{
mask = bswap_64(bswap_64(parts.start) & ((uint64_t) (~0) << (64 - prefix)));
memcpy(masked, &mask, sizeof(uint64_t));
return;
}
prefix -= 64;
memcpy(masked, &(parts.start), sizeof(uint64_t));
p += sizeof(uint64_t);
mask = bswap_64(bswap_64(parts.end) & (uint64_t) (~0) << (64 - prefix));
memcpy(p, &mask, sizeof(uint64_t));
}
int main (int argc, char **argv)
{
unsigned char packed[sizeof(struct in6_addr)];
unsigned char masked[sizeof(struct in6_addr)];
char buf[INET6_ADDRSTRLEN], *p;
int prefix = 56;
if (argc < 2)
return 1;
if ((p = strchr(argv[1], '/')))
{
*p++ = '\0';
prefix = atoi(p);
}
inet_pton(AF_INET6, argv[1], packed);
ipv6_prefix(masked, packed, prefix);
inet_ntop(AF_INET6, masked, buf, INET6_ADDRSTRLEN);
printf("prefix = %s/%d\n", buf, prefix);
return 0;
}
Nếu bạn viết 255.255.255.0 như/24 sau đó các bit không quan trọng là gần như giống hệt nhau. – Flexo
Lưu ý rằng bạn không nên sử dụng 'unsigned int' cho IPv4; bạn nên sử dụng 'uint32_t' (hoặc typedef của nó). –