Skip to content

Instantly share code, notes, and snippets.

@Kittoes0124
Last active July 21, 2023 02:16
Show Gist options
  • Save Kittoes0124/e51576aa442d5dc7f1340e09d46fdc69 to your computer and use it in GitHub Desktop.
Save Kittoes0124/e51576aa442d5dc7f1340e09d46fdc69 to your computer and use it in GitHub Desktop.
var decode = 4188287251U; // 4238739751U; // 4265539247U;
var encode = 4160962843U; // 4236695191U; // 2130976847U;
var sw = Stopwatch.StartNew();
for (var i = 1U; i <= (uint.MaxValue / 2); i += 4) {
var ei0 = unchecked((i + 0) * encode);
var ei1 = unchecked((i + 1) * encode);
var ei2 = unchecked((i + 2) * encode);
var ei3 = unchecked((i + 3) * encode);
var ipi0 = IpAddressV4.New(value: ei0);
var ipi1 = IpAddressV4.New(value: ei1);
var ipi2 = IpAddressV4.New(value: ei2);
var ipi3 = IpAddressV4.New(value: ei3);
var ci0 = ipi0.ToCoordinates();
var ci1 = ipi1.ToCoordinates();
var ci2 = ipi2.ToCoordinates();
var ci3 = ipi3.ToCoordinates();
Console.WriteLine($"i: {(ei0 * decode).ToString().PadLeft(10, '0')} | ip: {ipi0, 15} | w: {ci0.W, 3}, x: {ci0.X, 3}, y: {ci0.Y, 3}, z: {ci0.Z, 3}");
Console.WriteLine($"i: {(ei1 * decode).ToString().PadLeft(10, '0')} | ip: {ipi1, 15} | w: {ci1.W, 3}, x: {ci1.X, 3}, y: {ci1.Y, 3}, z: {ci1.Z, 3}");
Console.WriteLine($"i: {(ei2 * decode).ToString().PadLeft(10, '0')} | ip: {ipi2, 15} | w: {ci2.W, 3}, x: {ci2.X, 3}, y: {ci2.Y, 3}, z: {ci2.Z, 3}");
Console.WriteLine($"i: {(ei3 * decode).ToString().PadLeft(10, '0')} | ip: {ipi3, 15} | w: {ci3.W, 3}, x: {ci3.X, 3}, y: {ci3.Y, 3}, z: {ci3.Z, 3}");
Console.ReadKey(intercept: true);
}
Console.WriteLine(sw.Elapsed.TotalSeconds);
readonly struct Coordinates4D<T> where T : IBinaryInteger<T>
{
public static Coordinates4D<T> New(T w, T x, T y, T z) =>
new(w: w, x: x, y: y, z: z);
public T W { get; init; }
public T X { get; init; }
public T Y { get; init; }
public T Z { get; init; }
private Coordinates4D(T w, T x, T y, T z) {
W = w;
X = x;
Y = y;
Z = z;
}
}
readonly struct IpAddressV4
{
public static IpAddressV4 New(uint value) =>
new(value: value);
public static IpAddressV4 operator +(IpAddressV4 value, uint other) => New(value: (value.Value + other));
public static IpAddressV4 operator ++(IpAddressV4 value) => (value + 1U);
public static IpAddressV4 operator -(IpAddressV4 value, uint other) => New(value: (value.Value - other));
public static IpAddressV4 operator --(IpAddressV4 value) => (value - 1U);
public uint Value { get; init; }
private IpAddressV4(uint value) {
Value = value;
}
public Coordinates4D<byte> ToCoordinates() {
var (l, r) = Value.ElegantUnpair<uint, ushort>();
var (w, x) = l.ElegantUnpair<ushort, byte>();
var (y, z) = r.ElegantUnpair<ushort, byte>();
return Coordinates4D<byte>.New(w: w, x: x, y: y, z: z);
}
public override string ToString() {
var buffer = (stackalloc char[16]);
var length = FormatValue(
buffer: buffer,
value: (BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value: Value) : Value)
);
return new(buffer[..length]);
static int FormatValue<TChar>(Span<TChar> buffer, uint value) where TChar : unmanaged, IBinaryInteger<TChar> {
var index = FormatByte(buffer: buffer, ones: (value >> 24));
buffer[index++] = TChar.CreateTruncating(value: '.');
index += FormatByte(buffer: buffer[index..], ones: (value >> 16));
buffer[index++] = TChar.CreateTruncating(value: '.');
index += FormatByte(buffer: buffer[index..], ones: (value >> 8));
buffer[index++] = TChar.CreateTruncating(value: '.');
index += FormatByte(buffer: buffer[index..], ones: value);
return index;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int FormatByte(Span<TChar> buffer, uint ones) {
ones &= 0xFF;
if (ones >= 10) {
if (ones >= 100) {
(var hundredsAndTens, ones) = Math.DivRem(left: ones, right: 10);
(var hundreds, var tens) = Math.DivRem(left: hundredsAndTens, right: 10);
buffer[2] = TChar.CreateTruncating(value: ('0' + ones));
buffer[1] = TChar.CreateTruncating(value: ('0' + tens));
buffer[0] = TChar.CreateTruncating(value: ('0' + hundreds));
return 3;
}
else {
(var tens, ones) = Math.DivRem(left: ones, right: 10);
buffer[1] = TChar.CreateTruncating(value: ('0' + ones));
buffer[0] = TChar.CreateTruncating(value: ('0' + tens));
return 2;
}
}
else {
buffer[0] = TChar.CreateTruncating(value: ('0' + ones));
return 1;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment