これはCで書かれたサンプルプログラムです(私はC ++を知らないので)。かなり速いですが、あまり満足していません。多分誰かが私がそれを改善するのを手伝ってくれるでしょう。
編集:明らかに、PHPのみの質問に変わる前にこれを書きました。これをPHPに変換することは、読者の練習問題として残されています(ew)。
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
/*
* Syntax: ./ipv6_list <ip>/<cidr-prefix>
*/
int main(int argc, char **argv) {
uint8_t start[16];
uint8_t address[16];
uint8_t mask[16] = { 0 };
uint8_t prefix = 128;
char *prefix_location;
int i;
/* This is the octet that, when changed, will result in <IP> & <mask> != <start IP> */
int mask_check_octet = 0;
if(argc != 2)
return 1;
/* Find prefix */
if((prefix_location = strstr(argv[1], "/")) != NULL) {
char *prefix_search = prefix_location + 1;
char *prefix_remaining;
long prefix_test;
if(!isdigit(*prefix_search))
return 2;
errno = 0;
prefix_test = strtol(prefix_search, &prefix_remaining, 10);
if(errno == ERANGE || prefix_test < 0 || prefix_test > 128 || strcmp(prefix_remaining, "") != 0)
return 2;
prefix = (uint8_t)prefix_test;
*prefix_location = '\0'; /* So we can just pass argv[1] into inet_pton(3) */
}
/* Convert prefix into mask */
for(i = 0; i < 16; i++) {
if(prefix == 0)
break;
mask_check_octet = i;
if(prefix < 8) {
mask[i] = ~((1 << (8 - prefix)) - 1);
break;
}
else
mask[i] = UINT8_MAX;
prefix -= 8;
}
/* Find address */
if(inet_pton(AF_INET6, argv[1], start) != 1)
return 3;
/* Start at the beginning of the network */
for(i = 0; i < 16; i++) {
start[i] &= mask[i];
address[i] = start[i];
}
/* Iterate */
while((address[mask_check_octet] & mask[mask_check_octet]) == start[mask_check_octet]) {
char address_str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, address, address_str, sizeof(address_str));
printf("%s\n", address_str);
/* Add one to the address */
for(i = 15; i >= 0; i--) {
if(address[i] != UINT8_MAX)
break;
}
address[i]++;
for(i++; i < 16; i++)
address[i] = 0;
};
return 0;
}
while
標準のシェルコマンドを使用して、出力を制限できます(またはループを変更するだけです)。
nfontes@brioche:~$ ./ipv6_list '2607:fc50:0:d00::0/106' | head -n 200
2607:fc50:0:d00::
2607:fc50:0:d00::1
2607:fc50:0:d00::2
2607:fc50:0:d00::3
2607:fc50:0:d00::4
2607:fc50:0:d00::5
2607:fc50:0:d00::6
2607:fc50:0:d00::7
2607:fc50:0:d00::8
2607:fc50:0:d00::9
2607:fc50:0:d00::a
2607:fc50:0:d00::b
2607:fc50:0:d00::c
2607:fc50:0:d00::d
2607:fc50:0:d00::e
[...]
2607:fc50:0:d00::c0
2607:fc50:0:d00::c1
2607:fc50:0:d00::c2
2607:fc50:0:d00::c3
2607:fc50:0:d00::c4
2607:fc50:0:d00::c5
2607:fc50:0:d00::c6
2607:fc50:0:d00::c7