Skip to content

Instantly share code, notes, and snippets.

@Hafthor
Hafthor / nosuppress.cs
Last active July 16, 2025 16:05
Why you shouldn't call GC.SuppressFinalize(this) unless you directly have a finalizer
public class MyClass : MyDerivedClass {
public override void Dispose() {
base.Dispose();
GC.SuppressFinalize(this); // here we improperly call GC.SuppressFinalize(this)
}
}
public class MyDerivedClass : MyBaseClass {
public override void Dispose() {
; // oops, we forgot to call base.Dispose();
@Hafthor
Hafthor / DHECExplainer.cs
Created July 13, 2025 18:16
Explanation of how Diffie Hellman Elliptic Curve Key Exchange works
// Example:
// E: y^2 = x^3 + 2x + 2 (mod 17) - a=2, b=2
// G: (5, 1)
using Point = (int x, int y);
int a = 2, b = 2, mod = 17, Z = 19; // y^2 = x^3 + 2x + 2 (mod 17)
Point g = (5, 1); // G: (5,1)
Console.WriteLine($"G:{g}");
@Hafthor
Hafthor / RSAExplainer.cs
Last active July 15, 2025 00:43
Explanation of how RSA encryption and signatures work
using System.Diagnostics;
int p = 23, q = 29; // two private primes
int pubMod = p * q; // 667, the neighbor of the beast
// In practice, the primes used are crazy big (1024-bit each), making it infeasible to factor pubMod (2048-bit).
// Even if you could try 4B factors a second, on 4B machines, each with 4B CPUs, for 4B seconds (~126 years), you
// could only explore 128-bits worth of possibilities! And that doesn't mean you're an eighth of the way there. It
// would be if the number were 131-bits in length. Each extra bit doubles the effort required.
int pubExp = 257; // third Fermat prime (2^2^n+1, where n=3)
// The real RSA uses the fourth, and believed to be the last, Fermat prime, 2^2^4+1=65537.
@Hafthor
Hafthor / gcf.cs
Last active November 19, 2022 19:45
Greatest Common Factor using Euclid's algorithm and, gasp, gotos to be fast (about 50% faster)
static long gcf(long m, long n)
{
if (m < n) goto l2;
l1: if ((m %= n) == 0) return n;
l2: if ((n %= m) == 0) return m;
goto l1;
}
@Hafthor
Hafthor / ForwardCopy.cs
Last active August 21, 2022 00:22
Works like Array.Copy or Buffer.BlockCopy but with memcpy forward only operation vs memmove
public static void ForwardCopy(byte[] s, uint si, byte[] d, uint di, uint cx) {
unchecked {
// pre copy to qword align to destination
uint cxpre = (8 - (di & 7)) & 7;
if (cx < cxpre) {
// early out if we cannot even align to the first qword
for (int i = 0; i < cx; i++)
d[di++] = s[si++];
return;
}
@Hafthor
Hafthor / DisposableList.cs
Created August 7, 2022 04:53
For making a list of disposable items. Useful since you can using wrap the list create and add disposable items to it, like FileStreams.
public class DisposableList<T> : List<T>, IDisposable where T : IDisposable {
public void Dispose() {
foreach (var i in this) i.Dispose();
}
}
// Copyright (c) 2022 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
static unsafe void UnsafeSet(byte[] a, uint d, uint c, byte v) {
unchecked {
ushort v2 = (ushort)(v << 8 | v);
uint v4 = (uint)v2 << 16 | v2;
ulong v8 = (ulong)v4 << 32 | v4;
fixed (byte* p = a) {
byte* di = p + d;
// Copyright (c) 2022 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
static unsafe void UnsafeCopy(byte[] sa, uint s, byte[] da, uint d, uint c) {
unchecked {
fixed (byte* sp = sa, dp = da) {
byte* si = sp + s, di = dp + d;
if (c >= 1 && (d & 1) != 0) { // word align
*((byte*)di) = *((byte*)si);
si++; di++; c--; d++;
@Hafthor
Hafthor / jab.cs
Created June 17, 2022 01:00
minimal dependency injector
public class Jab : Attribute {
public T Resolve<T>() where T : class {
return (T)Resolve(typeof(T));
}
public object Resolve(Type typ) {
var typeToInstantiate = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsDefined(typeof(Jab), false) && t.IsClass && t.IsPublic && t.GetInterfaces().Contains(typ)
select t).Single();
var defaultConstructor = (from c in typeToInstantiate.GetConstructors().ToList()
@Hafthor
Hafthor / RubiksCube.java
Created January 17, 2022 22:35
command line rubik's cube
package com.hafthor;
import java.util.Scanner;
public class Main {
public static void main(final String[] args) {
final RubiksCube rc = new RubiksCube();
rc.print();
Scanner scanner = new Scanner(System.in);
for (; ; ) {