You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

34 lines
973 B

2 years ago
  1. let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes))
  2. let customAlphabet = (alphabet, defaultSize = 21) => {
  3. let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
  4. let step = -~((1.6 * mask * defaultSize) / alphabet.length)
  5. return async (size = defaultSize) => {
  6. let id = ''
  7. while (true) {
  8. let bytes = crypto.getRandomValues(new Uint8Array(step))
  9. let i = step
  10. while (i--) {
  11. id += alphabet[bytes[i] & mask] || ''
  12. if (id.length === size) return id
  13. }
  14. }
  15. }
  16. }
  17. let nanoid = async (size = 21) => {
  18. let id = ''
  19. let bytes = crypto.getRandomValues(new Uint8Array(size))
  20. while (size--) {
  21. let byte = bytes[size] & 63
  22. if (byte < 36) {
  23. id += byte.toString(36)
  24. } else if (byte < 62) {
  25. id += (byte - 26).toString(36).toUpperCase()
  26. } else if (byte < 63) {
  27. id += '_'
  28. } else {
  29. id += '-'
  30. }
  31. }
  32. return id
  33. }
  34. export { nanoid, customAlphabet, random }