Currently, I have the following two enum types:
[Flags]
public enum KeyboardLocks :
    byte
{
    None       = 0,
    NumLock    = 1 << 0,
    CapsLock   = 1 << 1,
    ScrollLock = 1 << 2
}
[Flags]
public enum KeyboardModifiers :
    byte
{
    None         = 0,
    LeftAlt      = 1 << 0,
    LeftControl  = 1 << 1,
    LeftShift    = 1 << 2,
    RightAlt     = 1 << 3,
    RightControl = 1 << 4,
    RightShift   = 1 << 5
}
These are both wrapped into a single state object, which represents the state of the modifier keys on the keyboard:
public struct ModifierState
{
    // (Constructor and get-only properties omitted)    
    public readonly KeyboardLocks Locks;
    public readonly KeyboardModifiers Modifiers;
    public override int GetHashCode()
    {
        int hash = 19;
        hash = (hash * 257) + Locks.GetHashCode();
        hash = (hash * 257) + Modifiers.GetHashCode();
        return hash;
    }
}
After doing a little bit of research, I found out that GetHashCode() will simply return the value for byte and int. I've looked at other questions, and it seems that the best approach is to pick two primes that don't overlap with the internal hash table.
I noticed that if I went with 17 and 23, as suggested, values would regularly collide (at least according to a spreadsheet I made). I used 19 and 257 instead, because it would assign each enum a unique value.
Am I missing the point here? I very rarely make types that need to override GetHashCode(), so I have no idea if this is remotely correct.
 
    