Skip to content

Adding support for randomUUID#197

Open
Dhruv-Maradiya wants to merge 3 commits intogoogle:masterfrom
Dhruv-Maradiya:features/add-uuid
Open

Adding support for randomUUID#197
Dhruv-Maradiya wants to merge 3 commits intogoogle:masterfrom
Dhruv-Maradiya:features/add-uuid

Conversation

@Dhruv-Maradiya
Copy link
Copy Markdown

@Dhruv-Maradiya Dhruv-Maradiya commented Mar 10, 2025

Implement randomUUID in webcrypto.dart

Changes

  • Added randomUUID() method.
  • Followed the W3C Web Crypto API specification.
  • Checked BoringSSL but couldn't find an existing randomUUID implementation, so implemented it based on the W3C spec.
  • Verified browser compatibility using Can I use—support looks good.

Testing

  • Added test cases to validate UUID generation.
  • Currently, the test runs a loop 100 times to generate UUIDs—open to feedback on whether this is the best approach.

Notes

Comment on lines +49 to +54
.map((e) => e.toRadixString(16).padLeft(2, '0'))
.join()
.replaceAllMapped(
RegExp(r'(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})'),
(m) => '${m[1]}-${m[2]}-${m[3]}-${m[4]}-${m[5]}',
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done this other places the classical implementation is:

final bytes = _randomBytes(16);
  // Set V4 bits according to:
  // https://tools.ietf.org/html/rfc4122#section-4.4
  bytes[6] = (bytes[6] & 0x0f) | 0x40;
  bytes[8] = (bytes[8] & 0x3f) | 0x80;

  // Encode as UUIDv4
  final s = hex.encode(bytes).substring;
  return '${s(0, 8)}-${s(8, 12)}-${s(12, 16)}-${s(16, 20)}-${s(20)}';

Maybe, using toRadixString is nicer, since it avoids a dependency on package:convert.

Comment on lines +37 to +40
final out = scope<ffi.Uint8>(16);
_checkOp(ssl.RAND_bytes(out, 16) == 1);

var bytes = out.asTypedList(16);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, we could just use fillRandomBytes, then we have less FFI stuff going on.

check(uuid[8] == '-');
check(uuid[13] == '-');
check(uuid[18] == '-');
check(uuid[23] == '-');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the bits too

/// }
///
/// ```
String randomUUID() => webCryptImpl.random.randomUUID();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generates a UUIDv4, there is a specification let's explain that:
https://tools.ietf.org/html/rfc4122#section-4.4

/// }
///
/// ```
String randomUUID() => webCryptImpl.random.randomUUID();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of the function in Dart should follow conventions:
https://dart.dev/effective-dart/style#do-capitalize-acronyms-and-abbreviations-longer-than-two-letters-like-words

randomUuid(), however, ugly 🙈

We could choose to just call it uuid(), I don't know. We do change names from Javascript when implementing them in Dart, like how getRandomValues became fillRandomBytes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HamdaanAliQuatil any thoughts on the name?

@Dhruv-Maradiya
Copy link
Copy Markdown
Author

Thank you for your feedback! I am currently in the middle of my examinations and will make the requested changes as soon as I get time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider adding support for randomUUID

2 participants