Salt a system hash¶
This operation (SaltHash) inserts each hex-encoded date part from _dateParts into the progressively growing hash string at a random position, recording each insertion in a location map prefixed to the result; the map is a fixed 42 characters wide only while each entry's unpadded body-length field renders as two digits (BR-HU-01). In-repo, SystemHashService.ComputeHash calls this immediately after constructing a salting SaltShaker (OP-HU-01).
| Field | Value |
|---|---|
| Operation ID | OP-HU-03 |
| Trigger | Called after OP-HU-01 (in-repo: SystemHashService.ComputeHash) |
| Inputs | systemHash (in-repo, a 44-char Base64 SHA-256 string) |
| Outputs | Salted hash string: a fixed 42-character location map (only while each entry's unpadded body-length field stays two digits) followed by the salted body, whose total string length varies with systemHash.Length plus the seven inserted date parts |
| Primary components | SaltShaker.SaltHash(string systemHash) |
| Entry point | src/SAIF.NetCore.HashUtil/SAIF.NetCore.HashUtil/SaltShaker.cs |
Steps¶
- Create an empty
StringBuilderto accumulate the location map. - For each entry of
_dateParts, in enumeration order Minute, Year, Day, Millisecond, Second, Hour, Month (BR-HU-04, BR-HU-06): - Pick a random insertion index in
[0, currentLength)of the string as it currently stands, after any prior insertions in this loop (BR-HU-05). - Pick a random filler pad character in the range
'A'–'Y'(BR-HU-07). - Insert the hex-encoded date part at the chosen index.
- Append the insertion index (zero-padded to 3 digits), the pad character, and the new total body length (an unpadded decimal number, two digits for the observed/assumed input shape) to the map (BR-HU-01).
- On failure: if the instance was built with the parameterless constructor (OP-HU-02), this step throws an unguarded
NullReferenceExceptionbecause_datePartsisnull(BR-HU-04). - Return the concatenation of the location map and the fully salted
systemHashbody — the map is 42 characters wide only when every body-length field rendered as two digits (bodies of 10–99 characters after each insertion); the total returned string length is otherwise variable, and unsupported body lengths may still be returned without a round-trip guarantee (BR-HU-01). - On failure: if
systemHashisnull, this operation throws an unguardedNullReferenceException; ifsystemHashis empty,Random.Next(0,0)returns 0 and insertion proceeds without error.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([Called after OP-HU-01]) --> S1[Create empty map StringBuilder]
S1 --> Loop{For each date part in<br>Minute..Month order}
Loop -->|next part| S2[Pick random insertion index]
S2 --> S3["Pick random pad char 'A'-'Y'"]
S3 --> S4[Insert hex-encoded part at index]
S4 --> S5["Append index + pad + body length to map"]
S5 --> Loop
Loop -->|all parts done| S6["Return map + salted systemHash"]
S6 --> EndOk([Salted hash string returned])
S2 -->|_dateParts null| EndErr([NullReferenceException])
Failure and edge-case behavior¶
- Parameterless-constructed instance (OP-HU-02):
NullReferenceExceptioniterating_dateParts. nullsystemHash:NullReferenceExceptionreadingsystemHash.Length.- Empty
systemHash: proceeds without error;Random.Next(0,0)returns0. - No validation exists for the post-insertion body length staying within the 2-digit (10–99 character) range assumed by the fixed-width map (BR-HU-01).
Related documentation¶
Sources¶
src/SAIF.NetCore.HashUtil/SAIF.NetCore.HashUtil/SaltShaker.cssrc/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SystemHashService.cs