he number of octets to consider in ip (4 or 8)
uint8_t node_id[20]; // resulting node ID

uint8_t v4_mask[] = { 0x03, 0x0f, 0x3f, 0xff };
uint8_t v6_mask[] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
uint8_t* mask = num_octets == 4 ? v4_mask : v6_mask;

for (int i = 0; i &lt; num_octets; ++i)
        ip[i] &amp;= mask[i];

uint32_t rand = std::rand() &amp; 0xff;
uint8_t r = rand &amp; 0x7;
ip[0] |= r &lt;&lt; 5;

uint32_t crc = 0;
crc = crc32c(crc, ip, num_octets);

// only take the top 21 bits fr