A salted hash is prefixed with a location map composed of seven 6-character entries (3-digit zero-padded index + pad char + unpadded decimal body length), one per embedded date part. The map is a fixed 42 characters wide only when each entry's body-length field happens to render as two digits (total salted string length between 10 and 99 characters at that insertion step); SaltHash appends systemHash.Length with no padding or width validation.
BlandHash always reads exactly 42 characters as the map, so any entry whose body-length field is not two digits shifts every following map entry and corrupts or breaks decoding; SaltHash does not enforce or validate that the salted length stays in the 10–99 range before emitting output.
The embedded timestamp has millisecond precision and uses 24-hour hours; it is captured with culture-sensitive DateTime.ToString and reconstructed with culture-sensitive Convert.ToDateTime("yyyy/MM/dd HH:mm:ss.fff"). No time-zone/DateTimeKind information is embedded.*
Trigger
SaltShaker(DateTime); BlandHash
Enforcement
SaltShaker..ctor(DateTime); SaltShaker.BlandHash
Outcome
The recovered DateTime equals the create date to the millisecond under a culture whose date/time parsing accepts this layout; the recovered DateTimeKind is unspecified/local.*
Each date part is inserted at a uniformly random index in [0, currentLength) of the progressively salted string, so placement is randomized rather than fixed across calls.
Trigger
Each loop iteration in SaltHash
Enforcement
SaltShaker.SaltHash using System.Random
Outcome
Output is randomized and typically differs between salts of the same hash and date, but Random.Next can produce the same index or pad character on different calls — the source performs no duplicate-detection or uniqueness check, so distinct output is not guaranteed.
Parts are inserted in order Minute→Year→Day→Millisecond→Second→Hour→Month and removed in exact reverse order using the reversed map, so every recorded index is valid at removal time.
Trigger
SaltHash, BlandHash
Enforcement
SaltShaker._dateParts population order; SaltShaker._datePartLength order; SaltShaker.BlandHash reversal and SplitAndReverse
Outcome
Lossless recovery of the original hash. Relies on Dictionary enumeration order remaining stable.*
Correct when the map appears only as the prefix (practically always); would corrupt the body if the 42-character sequence recurred elsewhere in the body.*
An expired system hash is reported with a fixed message containing the hash's embedded date and the evaluation date, both formatted MM/dd/yyyy hh:mm:ss.ffffff.
Trigger
Consumer constructs and throws the exception
Enforcement
SystemHashExpiredException..ctor
Outcome
The exception message is fixed as described; the 12-hour clock without an AM/PM designator makes the times ambiguous. The decision to throw is made entirely by SAIF.NetCore.SystemHash (SystemHashService.RemoveSystemHashSaltAndValidateLifetime), not by this library.
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.