legacy.odin 3.2 KB

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