using System.Security.Cryptography;
using System.Text;
namespace Nuuru.Server.Utilities
{
public static class IpCloaker
{
///
/// Cloaks an IPv4 address so that each segment's output depends on all preceding segments.
/// Two IPs sharing a prefix (e.g. same /24) will share the same cloaked prefix.
///
public static string Cloak(string ipAddress, byte[] key)
{
if (string.IsNullOrEmpty(ipAddress))
return ipAddress;
var parts = ipAddress.Split('.');
if (parts.Length != 4)
return CloakNonIpv4(ipAddress, key);
var octets = new byte[4];
for (int i = 0; i < 4; i++)
{
if (!byte.TryParse(parts[i], out octets[i]))
return CloakNonIpv4(ipAddress, key);
}
var segments = new string[4];
using var hmac = new HMACSHA256(key);
for (int i = 0; i < 4; i++)
{
var hash = hmac.ComputeHash(octets, 0, i + 1);
segments[i] = Convert.ToHexString(hash, 0, 2).ToLowerInvariant();
}
return string.Join(":", segments);
}
///
/// Fallback for IPv6 or other formats — hash the whole thing.
///
private static string CloakNonIpv4(string ipAddress, byte[] key)
{
using var hmac = new HMACSHA256(key);
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(ipAddress));
return Convert.ToHexString(hash, 0, 8).ToLowerInvariant();
}
}
}