OK , Je l'ai fait en C plutôt qu'en C++, mais ça devrait marcher. En outre, il utilise bswap_64 qui est AFAIK une extension GNU donc peut ne pas fonctionner sur tout.
Il semble être très rapide sur amd64, et plus rapide que la solution actuelle Yasar est venu avec:
#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;
}
Si vous écrivez 255.255.255.0 comme/24 alors le tripoter bit est presque identique. – Flexo
Notez que vous ne devez pas non plus utiliser 'unsigned int' pour IPv4; vous devriez utiliser 'uint32_t' (ou un typedef de celui-ci). –