File size: 1,229 Bytes
45dc401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php

declare(strict_types=1);

namespace App\Domain\Analytics;

/**
 * Coarsens an IP address before any persistence.
 * Raw IPs are never stored β€” only the anonymised form is passed to the job.
 *
 * IPv4:  zeros the last octet        1.2.3.4   β†’ 1.2.3.0
 * IPv6:  keeps the first 48 bits     2001:db8::1 β†’ 2001:db8::/48 prefix as string
 * Invalid / empty: returns '0.0.0.0'
 */
final class AnalyticsIpAnonymizer
{
    public static function coarsen(string $ip): string
    {
        $ip = trim($ip);

        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
            $parts    = explode('.', $ip);
            $parts[3] = '0';
            return implode('.', $parts);
        }

        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
            // Expand to full 128-bit representation, keep first 48 bits (/48 prefix).
            $packed  = inet_pton($ip);
            if ($packed === false) {
                return '0.0.0.0';
            }
            // Zero bytes 7–15 (keep bytes 0–5, 48 bits)
            $zeroed  = substr($packed, 0, 6) . str_repeat("\x00", 10);
            return inet_ntop($zeroed) . '/48';
        }

        return '0.0.0.0';
    }
}