package org.stagemonitor.tracing.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; public final class IPAnonymizationUtils { private static final Logger logger = LoggerFactory.getLogger(IPAnonymizationUtils.class); private static final int ANONYMIZED_IPV4_OCTETS = 1; private static final int ANONYMIZED_IPV6_OCTETS = 10; private IPAnonymizationUtils() { // don't instantiate } /** * Anonymizes IPv4 and IPv6 addresses * <p/> * For IPv4 addresses, the last octet is set to zero. * If the address is a IPv6 address, the last 80 bits (10 bytes) are set to zero. * <p/> * This is just like Google Analytics handles IP anonymization: https://support.google.com/analytics/answer/2763052 * * @param clientIp the full IPv4 or IPv6 address * @return the anonymized IP address or null, if the provided ip address is invalid */ public static String anonymize(String clientIp) { // prevents DNS lookups if (clientIp == null || (!InetAddressUtils.isIPv4Address(clientIp) && !InetAddressUtils.isIPv6Address(clientIp))) { return null; } try { // if clientIp is not a ip address, that would perform a DNS lookup final InetAddress inetAddress = InetAddress.getByName(clientIp); if (inetAddress instanceof Inet4Address) { final Inet4Address inet4Address = (Inet4Address) inetAddress; final byte[] address = inet4Address.getAddress(); anonymizeLastBytes(address, ANONYMIZED_IPV4_OCTETS); return InetAddress.getByAddress(address).toString().substring(1); } else if (inetAddress instanceof Inet6Address) { final Inet6Address inet6Address = (Inet6Address) inetAddress; final byte[] address = inet6Address.getAddress(); anonymizeLastBytes(address, ANONYMIZED_IPV6_OCTETS); return InetAddress.getByAddress(address).toString().substring(1); } } catch (UnknownHostException e) { logger.warn(e.getMessage(), e); } return null; } private static void anonymizeLastBytes(final byte[] address, final int bytesToAnonymize) { for (int i = bytesToAnonymize; i > 0; i--) { address[address.length - i] = 0; } } }