SHA-1 is a cryptographic hash function. Although it is no longer considered cryptographically secure (as collisions can be found faster than brute force), it is still very suitable for a broad range of uses, and is a lot stronger than MD5.
This package provides a way of creating SHA-1 digests from String
s, Bytes
, or
List Int
s (where each Int
is between 0 and 255, and represents a byte).
It can also take those Digest
s and format them in hexadecimal or base64
notation. Alternatively, you can get the binary digest, using either Bytes
or
List Int
to represent the bytes.
A type to represent a message digest. SHA1.Digest
s are equatable, and you may
want to consider keeping any digests you need in your Model
as Digest
s, not
as String
s created by toHex
or toBase64
.
fromString : String -> Digest
Create a digest from a String
.
"hello world" |> SHA1.fromString |> SHA1.toHex
--> "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"
toHex : Digest -> String
One of the two canonical ways of representing a SHA-1 digest is with 40 hexadecimal digits.
"And our friends are all aboard"
|> SHA1.fromString
|> SHA1.toHex
--> "f9a0c23ddcd40f6956b0cf59cd9b8800d71de73d"
toBase64 : Digest -> String
One of the two canonical ways of representing a SHA-1 digest is in a 20 digit long Base64 binary to ASCII text encoding.
"Many more of them live next door"
|> SHA1.fromString
|> SHA1.toBase64
--> "jfL0oVb5xakab6BMLplGe2XPbj8="
fromBytes : Bytes -> Digest
Create a digest from Bytes
import Bytes.Encode as Encode
import Bytes exposing (Bytes, Endianness(..))
42
|> Encode.unsignedInt32 BE
|> Encode.encode
|> SHA1.fromBytes
|> SHA1.toHex
--> "25f0c736f1fad0770bbb9a265ded159517c1e68c"
fromByteValues : List Basics.Int -> Digest
Sometimes you have binary data that's not representable in a string. Create
a digest from the raw "bytes", i.e. a List
of Int
s. Any items not between 0
and 255 are discarded.
SHA1.fromByteValues [72, 105, 33, 32, 240, 159, 152, 132]
--> SHA1.fromString "Hi! 😄"
[0x00, 0xFF, 0x34, 0xA5] |> SHA1.fromByteValues |> SHA1.toBase64
--> "sVQuFckyE6K3fsdLmLHmq8+J738="
toByteValues : Digest -> List Basics.Int
Turn a digest into List Int
, each Int
representing a byte of data.
"And the band begins to play"
|> SHA1.fromString
|> SHA1.toByteValues
--> [ 0xF3, 0x08, 0x73, 0x13
--> , 0xD6, 0xBC, 0xE5, 0x5B
--> , 0x60, 0x0C, 0x69, 0x2F
--> , 0xE0, 0x92, 0xF4, 0x53
--> , 0x87, 0x3F, 0xAE, 0x91
--> ]
toInt32s : Digest -> { a : Basics.Int, b : Basics.Int, c : Basics.Int, d : Basics.Int, e : Basics.Int }
Internally, Digest
models its 160 bits of data in 5 (unsigned 32-bit)
Int
s. If you really want to get the raw digest data for your own data
processing, this function will allow you to do that.
"And the band begins to play"
|> SHA1.fromString
|> SHA1.toInt32s
--> { a = 0xF3087313
--> , b = 0xD6BCE55B
--> , c = 0x600C692F
--> , d = 0xE092F453
--> , e = 0x873FAE91
--> }