Files
managed-git/Git/Hash.fs
2023-09-02 21:48:31 +01:00

56 lines
1.4 KiB
Forth

namespace Git
open System
open System.Globalization
open System.Text
type Hash =
private
| Hash of byte array
override this.ToString () =
match this with
| Hash h ->
let t = StringBuilder (h.Length * 2)
for b in h do
t.AppendFormat ("{0:x2}", b) |> ignore
t.ToString ()
[<RequireQualifiedAccess>]
module Hash =
let ofBytes (s : byte array) = s |> Hash
let ofString (s : string) : Hash =
let rec b (pos : int) =
seq {
if pos < s.Length then
yield Byte.Parse (s.Substring (pos, 2), NumberStyles.AllowHexSpecifier)
yield! b (pos + 2)
}
b 0 |> Seq.toArray |> ofBytes
// Given a byte array of *characters* spelling out e.g. 'b' 'd' '6' '3', return the hash this is spelling out.
let ofSpelling (input : byte array) : Hash =
let inline value (b : byte) =
let c = char b
if '0' <= c && c <= '9' then
b - byte '0'
elif 'A' <= c && c <= 'F' then
b - (byte 'A') + 10uy
elif 'a' <= c && c <= 'f' then
b - (byte 'a') + 10uy
else
failwithf "Byte '%i' ('%c') is not a hex digit" b (char b)
fun i -> value input.[2 * i] * 16uy + value input.[2 * i + 1]
|> Array.init (input.Length / 2)
|> ofBytes
let toString (h : Hash) : string = h.ToString ()