import pyodbc def get_user(username) -> int: with pyodbc.connect("Server=(LocalDB)\Test; Integrated Security=true; Driver={ODBC Driver 17 for SQL Server}") as conn: with conn.execute("SELECT id FROM Users WHERE username=?", username) as cursor: rows = cursor.fetchall() if len(rows) <= 0: return return rows[0].id print(f"user ID: {get_user("EGS")}")
EGS 305
Just putting stuff I find out over here, so I can remember and find them more easily.
16 August 2025
Python - Execute a query with pyodbc
24 June 2025
.NET - Read/write a binary file line by line
To read a text file, you can use a StreamReader, but to read a binary file, you need a BinaryReader.This is how you use it:
if (File.Exists(FILENAME)) { using (var stream = new FileStream(FILENAME, FileMode.Open)) using (var reader = new BinaryReader(stream)) { if (stream.Length <= 0) return; //The file is empty. int i = reader.ReadInt32(); string s = reader.ReadString(); } }
Writing is similar:
using (var stream = new FileStream(SaveFilePath, FileMode.Create)) using (var writer = new BinaryWriter(stream)) { writer.Write(305); writer.Write("EGS"); }
The file will be automatically created if it doesn't exist yet.
11 November 2024
Windows API - Set the icon of a window created with P/Invoke
var icon = new Icon(GetResourceStream("Cards.ico"));
GetResourceStream is a custom method of mine to load the icon file from the embedded resources.
To create the window, you already defined a window class struct somewhere.var windowClass = new WindowClassEx();All you have to do, is pass the icon's internal handle to this structure.
windowClass.Icon = icon.Handle;And make sure the icon object is not destroyed while the window is open.
Windows will look for a small icon for the title bar in Icon when IconSmall is not set.
29 January 2024
GIT - avoid merge-commits
git pull --rebase
12 October 2023
GIT - rename a branch
Here's how to rename a GIT branch from Windows Explorer. This assumes GIT is installed on the computer.
- Enter
git branch -m "{new name}"
. - Enter
git push origin :"{old name}" "{new name}"
. - Enter
git push origin -u "{new name}"
.
22 September 2023
GIT - commit changes
Here's how to commit changes to GIT from Windows Explorer when the IDE doesn't have built-in support for GIT. This assumes GIT is installed on the computer.
- In Explorer, navigate to the root folder of the project and choose
File > Open command prompt
. - Alternatively, run the command prompt; enter
{drive letter}:
unless the project is on the C drive; then entercd "{full path to project root}"
. - Enter
git add .
to add new files. - Enter
git commit -m "{description of the commit}"
. - Enter
git push
.
04 August 2023
MFA - Generate time-based one-time passwords (TOTP)
I had to implement MFA for a web application. I needed to generate a key the user could save in an authenticator app. My application had to use this key to generate a code to validate the authenticator codes the user would enter.
Generate the key
Generate a truly random sequence of bytes and convert them to base32. I'm using the default SHA1 algorithm to generate keys of twenty characters.
const string BASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; using (var gen = new RNGCryptoServiceProvider()) //Use a cryptographically secure provider! { byte[] bytes = new byte[HMACSHA1.Create().HashSize / 8]; gen.GetBytes(bytes); //Fills the array with 20 bytes byte[] base32 = new byte[bytes.Length]; double d = (double)byte.MaxValue / (double)BASE32_CHARS.Length; for (int i = 0; i < bytes.Length; i++) { double c = (double)bytes[i]; int j = (int)Math.Floor(c / d); //If c is 255, j is 32, which is out of bounds! base32[i] = (byte)BASE32_CHARS[j < BASE32_CHARS.Length ? j : BASE32_CHARS.Length - 1]; //Scale from 255 to # of possible chars } return Encoding.ASCII.GetString(base32); }
Generate a code
First calculate the number of intervals that passed since the reference time. This time is usually the unix epoch of 1 january 1970 0:00:00 UTC. Then decode the base32 key and use it to hash the interval counter. Finally use this hash to generate a code like an authenticator app would.
const uint INTERVAL = 30; //The default of 30 seconds const uint CODE_LENGTH = 6; //The default of 6 digits double seconds = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; ulong counter = (ulong)Math.Floor(seconds / INTERVAL); byte[] counterBytes = BitConverter.GetBytes(counter); Array.Reverse(counterBytes); //Must be big-endian while .net is little-endian var hmac = HMACSHA1.Create(); hmac.Key = DecodeBase32(key); hmac.ComputeHash(counterBytes); int offset = hmac.Hash[hmac.Hash.Length - 1] & 0xf; int bin = (hmac.Hash[offset + 0] & 0x7f) << 24 | (hmac.Hash[offset + 1] & 0xff) << 16 | (hmac.Hash[offset + 2] & 0xff) << 8 | (hmac.Hash[offset + 3] & 0xff); return bin % (int)Math.Pow(10, CODE_LENGTH);
DecodeBase32(string value):
var base32 = BASE32_CHARS.Select((c, i) => new { c, i }).ToDictionary(ch => ch.c, ch => ch.i); //Each char and it's 0–31 index string bits = string.Concat(value.Select(c => Convert.ToString(base32[c], 2).PadLeft(5, '0'))); //A string of 0's en 1's return Enumerable.Range(0, bits.Length / 8).Select(i => Convert.ToByte(bits.Substring(i * 8, 8), 2)).ToArray();