legacy.odin 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. Versions 3 and 5 of `UUID` generation, both of which use legacy (`MD5` + `SHA1`) hashes.
  3. Those are known these days to no longer be secure.
  4. */
  5. package uuid_legacy
  6. import "base:runtime"
  7. import "core:crypto/legacy/md5"
  8. import "core:crypto/legacy/sha1"
  9. import "core:encoding/uuid"
  10. Identifier :: uuid.Identifier
  11. VERSION_BYTE_INDEX :: uuid.VERSION_BYTE_INDEX
  12. VARIANT_BYTE_INDEX :: uuid.VARIANT_BYTE_INDEX
  13. /*
  14. Generate a version 3 UUID.
  15. This UUID is generated with a MD5 hash of a name and a namespace.
  16. Inputs:
  17. - namespace: An `Identifier` that is used to represent the underlying namespace.
  18. This can be any one of the `Namespace_*` values provided in the `uuid` package.
  19. - name: The byte slice which will be hashed with the namespace.
  20. Returns:
  21. - result: The generated UUID.
  22. */
  23. generate_v3_bytes :: proc(
  24. namespace: Identifier,
  25. name: []byte,
  26. ) -> (
  27. result: Identifier,
  28. ) {
  29. namespace := namespace
  30. ctx: md5.Context
  31. md5.init(&ctx)
  32. md5.update(&ctx, namespace[:])
  33. md5.update(&ctx, name)
  34. md5.final(&ctx, result[:])
  35. result[VERSION_BYTE_INDEX] &= 0x0F
  36. result[VERSION_BYTE_INDEX] |= 0x30
  37. result[VARIANT_BYTE_INDEX] &= 0x3F
  38. result[VARIANT_BYTE_INDEX] |= 0x80
  39. return
  40. }
  41. /*
  42. Generate a version 3 UUID.
  43. This UUID is generated with a MD5 hash of a name and a namespace.
  44. Inputs:
  45. - namespace: An `Identifier` that is used to represent the underlying namespace.
  46. This can be any one of the `Namespace_*` values provided in the `uuid` package.
  47. - name: The string which will be hashed with the namespace.
  48. Returns:
  49. - result: The generated UUID.
  50. */
  51. generate_v3_string :: proc(
  52. namespace: Identifier,
  53. name: string,
  54. ) -> (
  55. result: Identifier,
  56. ) {
  57. return generate_v3_bytes(namespace, transmute([]byte)name)
  58. }
  59. generate_v3 :: proc {
  60. generate_v3_bytes,
  61. generate_v3_string,
  62. }
  63. /*
  64. Generate a version 5 UUID.
  65. This UUID is generated with a SHA1 hash of a name and a namespace.
  66. Inputs:
  67. - namespace: An `Identifier` that is used to represent the underlying namespace.
  68. This can be any one of the `Namespace_*` values provided in the `uuid` package.
  69. - name: The byte slice which will be hashed with the namespace.
  70. Returns:
  71. - result: The generated UUID.
  72. */
  73. generate_v5_bytes :: proc(
  74. namespace: Identifier,
  75. name: []byte,
  76. ) -> (
  77. result: Identifier,
  78. ) {
  79. namespace := namespace
  80. digest: [sha1.DIGEST_SIZE]byte
  81. ctx: sha1.Context
  82. sha1.init(&ctx)
  83. sha1.update(&ctx, namespace[:])
  84. sha1.update(&ctx, name)
  85. sha1.final(&ctx, digest[:])
  86. runtime.mem_copy_non_overlapping(&result, &digest, 16)
  87. result[VERSION_BYTE_INDEX] &= 0x0F
  88. result[VERSION_BYTE_INDEX] |= 0x50
  89. result[VARIANT_BYTE_INDEX] &= 0x3F
  90. result[VARIANT_BYTE_INDEX] |= 0x80
  91. return
  92. }
  93. /*
  94. Generate a version 5 UUID.
  95. This UUID is generated with a SHA1 hash of a name and a namespace.
  96. Inputs:
  97. - namespace: An `Identifier` that is used to represent the underlying namespace.
  98. This can be any one of the `Namespace_*` values provided in the `uuid` package.
  99. - name: The string which will be hashed with the namespace.
  100. Returns:
  101. - result: The generated UUID.
  102. */
  103. generate_v5_string :: proc(
  104. namespace: Identifier,
  105. name: string,
  106. ) -> (
  107. result: Identifier,
  108. ) {
  109. return generate_v5_bytes(namespace, transmute([]byte)name)
  110. }
  111. generate_v5 :: proc {
  112. generate_v5_bytes,
  113. generate_v5_string,
  114. }