mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 11:52:22 -07:00
161 lines
3.6 KiB
Odin
161 lines
3.6 KiB
Odin
package uuid
|
|
|
|
import "core:crypto/legacy/md5"
|
|
import "core:crypto/legacy/sha1"
|
|
import "core:math/rand"
|
|
import "core:mem"
|
|
|
|
/*
|
|
Generate a version 3 UUID.
|
|
|
|
This UUID is generated from a name within a namespace.
|
|
MD5 is used to hash the name with the namespace to produce the UUID.
|
|
|
|
Inputs:
|
|
- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
This can be any one of the `Namespace_*` values provided in this package.
|
|
- name: The byte slice used to generate the name on top of the namespace.
|
|
|
|
Returns:
|
|
- result: The generated UUID.
|
|
*/
|
|
generate_v3_bytes :: proc(
|
|
namespace: Identifier,
|
|
name: []byte,
|
|
) -> (
|
|
result: Identifier,
|
|
) {
|
|
namespace := namespace
|
|
|
|
ctx: md5.Context
|
|
md5.init(&ctx)
|
|
md5.update(&ctx, namespace[:])
|
|
md5.update(&ctx, name)
|
|
md5.final(&ctx, result[:])
|
|
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] |= 0x30
|
|
|
|
result[VARIANT_BYTE_INDEX] &= 0x3F
|
|
result[VARIANT_BYTE_INDEX] |= 0x80
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
Generate a version 3 UUID.
|
|
|
|
This UUID is generated from a name within a namespace.
|
|
MD5 is used to hash the name with the namespace to produce the UUID.
|
|
|
|
Inputs:
|
|
- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
This can be any one of the `Namespace_*` values provided in this package.
|
|
- name: The string used to generate the name on top of the namespace.
|
|
|
|
Returns:
|
|
- result: The generated UUID.
|
|
*/
|
|
generate_v3_string :: proc(
|
|
namespace: Identifier,
|
|
name: string,
|
|
) -> (
|
|
result: Identifier,
|
|
) {
|
|
return generate_v3_bytes(namespace, transmute([]byte)name)
|
|
}
|
|
|
|
generate_v3 :: proc {
|
|
generate_v3_bytes,
|
|
generate_v3_string,
|
|
}
|
|
|
|
/*
|
|
Generate a version 4 UUID.
|
|
|
|
This UUID will be pseudorandom, save for 6 pre-determined version and variant bits.
|
|
|
|
Returns:
|
|
- result: The generated UUID.
|
|
*/
|
|
generate_v4 :: proc() -> (result: Identifier) {
|
|
bytes_generated := rand.read(result[:])
|
|
assert(bytes_generated == 16, "RNG failed to generate 16 bytes for UUID v4.")
|
|
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] |= 0x40
|
|
|
|
result[VARIANT_BYTE_INDEX] &= 0x3F
|
|
result[VARIANT_BYTE_INDEX] |= 0x80
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
Generate a version 5 UUID.
|
|
|
|
This UUID is generated from a name within a namespace.
|
|
SHA1 is used to hash the name with the namespace to produce the UUID.
|
|
|
|
Inputs:
|
|
- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
This can be any one of the `Namespace_*` values provided in this package.
|
|
- name: The byte slice used to generate the name on top of the namespace.
|
|
|
|
Returns:
|
|
- result: The generated UUID.
|
|
*/
|
|
generate_v5_bytes :: proc(
|
|
namespace: Identifier,
|
|
name: []byte,
|
|
) -> (
|
|
result: Identifier,
|
|
) {
|
|
namespace := namespace
|
|
digest: [sha1.DIGEST_SIZE]byte
|
|
|
|
ctx: sha1.Context
|
|
sha1.init(&ctx)
|
|
sha1.update(&ctx, namespace[:])
|
|
sha1.update(&ctx, name)
|
|
sha1.final(&ctx, digest[:])
|
|
|
|
mem.copy_non_overlapping(&result, &digest, 16)
|
|
|
|
result[VERSION_BYTE_INDEX] &= 0x0F
|
|
result[VERSION_BYTE_INDEX] |= 0x50
|
|
|
|
result[VARIANT_BYTE_INDEX] &= 0x3F
|
|
result[VARIANT_BYTE_INDEX] |= 0x80
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
Generate a version 5 UUID.
|
|
|
|
This UUID is generated from a name within a namespace.
|
|
SHA1 is used to hash the name with the namespace to produce the UUID.
|
|
|
|
Inputs:
|
|
- namespace: Another `Identifier` that is used to represent the underlying namespace.
|
|
This can be any one of the `Namespace_*` values provided in this package.
|
|
- name: The string used to generate the name on top of the namespace.
|
|
|
|
Returns:
|
|
- result: The generated UUID.
|
|
*/
|
|
generate_v5_string :: proc(
|
|
namespace: Identifier,
|
|
name: string,
|
|
) -> (
|
|
result: Identifier,
|
|
) {
|
|
return generate_v5_bytes(namespace, transmute([]byte)name)
|
|
}
|
|
|
|
generate_v5 :: proc {
|
|
generate_v5_bytes,
|
|
generate_v5_string,
|
|
}
|