
Research
/Security News
Toptal’s GitHub Organization Hijacked: 10 Malicious Packages Published
Threat actors hijacked Toptal’s GitHub org, publishing npm packages with malicious payloads that steal tokens and attempt to wipe victim systems.
C# implementation of UUID v7 time-sortable Guids ("06338364-8305-788f-8000-9ada942eb663"), and an alternative string format Id25 ("0q974fmmvghw8qfathid7qekc").
This C# project implements UUID v7 as described in Peabody and Davis. This is the latest IETF draft for UUIDs that are time-sortable and have a random component to guarantee uniqueness.
It is available on NuGet as UuidExtensions
.
The internal structure of the UUID uses:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix ts (32 + 4 = 36 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|unix ts| msec (12 bits) | ver | usec (12 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var| seq (14 bits) | rand (16 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rand (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Here is a pair of Uuid7s, one as a Guid and the other as a string, illustrating how their string representations are time-ordered:
var uuid7 = new Uuid7();
Guid g1 = uuid7.Guid(); // e.g. 06338364-8305-788f-8000-9ada942eb663
string s2 = uuid7.String(); // 06338364-8305-7b74-8000-de4963503139
Assert.IsTrue(String.Compare(g1.ToString(), s2) < 0);
Note that internally, Microsoft stores Guids using big endian for the first three
components and little endian for the last two. So UUID v7 Guids
are only time-ordered using guid.ToString()
, not using guid.ToByteArray()
.
Id25
string formatThis package also supports an alternative string representation that I call Id25
.
The goal here is to represent UUID v7 as the shortest possible
alphanumeric string that is simple for humans to say and use. That is:
a-z
is not needed, drop first l
and then o
since
these are the letters most easily confused with digits 1
and 0
.To see why Id25 must be 25 characters long, UUIDs have 128 bits.
An alphabet of 36 characters (0-9, a-z
) would need a string representation
$128/log_2(36) = 24.75$ characters long, which gets rounded up to 25.
Now $128/log_2(35) = 24.95$, also just under 25. So we can drop one character from the
alphabet and keep the string length the same. According to the criteria above,
we should drop l
, resulting in the 35-character alphabet 0-9, a-k, m-z
.
Finally, note this alphabet must put the digits before the letters so that the strings come out properly time-ordered.
var uuid7 = new Uuid7();
string s1 = uuid7.Id25(); // e.g. 0q994uri6sp53j3eu7bty4wsv
string s2 = uuid7.Id25(); // 0q994uri70qe0gjxrq8iv4iyu
Assert.IsTrue(String.Compare(s1, s2) < 0);
The timestamp may be specified explicitly by passing in the time expressed as the whole number of nanoseconds since 00:00:00 on 1 January 1970 UTC. Here are two Id25 strings nominally 1ns apart, and a third at the same timestamp as the second.
var uuid7 = new Uuid7();
long t1 = Uuid7.TimeNs();
long t2 = t1 + 1;
string s1 = uuid7.Id25(t1); // e.g. 0q996kioxxyfds1stmjqajen6
string s2 = uuid7.Id25(t2); // 0q996kioxxyfj83w8bqp67d2j
string s3 = uuid7.Id25(t2); // 0q996kioxxyfj83z4pmujhrx4
Assert.IsTrue(String.Compare(s1, s2) < 0);
Assert.IsTrue(String.Compare(s2, s3) < 0);
Note that the second and the third have been generated from the same
Uuid7
object. Its internal sequence counter ensures successive
UUIDv7/Id25 values remain time-ordered even if they have the
same timestamp.
The sequence counter resets when the timestamp changes.
In this final example, we cannot tell whether s1 > s3
or not.
That is determined by the lower 36 random bits of the two UUIDs.
string s1 = uuid7.Id25(t1);
string s2 = uuid7.Id25(t2);
string s3 = uuid7.Id25(t1);
A simple console app prints out the current timestamp's Uuid7 in both UUID and Id25 forms. It also does a simple timing check to calculate the underlying clock precision.
> dotnet run
0634194d-3e69-72a4-8000-d602a09b0e94 0q9khv3tqz7e3jfv1v0i42yz0
Precision is 2852ns rather than 1863ns (653 unique timestamps from 1,000 loops taking 1.8626ms)
FAQs
C# implementation of UUID v7 time-sortable Guids ("06338364-8305-788f-8000-9ada942eb663"), and an alternative string format Id25 ("0q974fmmvghw8qfathid7qekc").
We found that uuidextensions demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Threat actors hijacked Toptal’s GitHub org, publishing npm packages with malicious payloads that steal tokens and attempt to wipe victim systems.
Research
/Security News
Socket researchers investigate 4 malicious npm and PyPI packages with 56,000+ downloads that install surveillance malware.
Security News
The ongoing npm phishing campaign escalates as attackers hijack the popular 'is' package, embedding malware in multiple versions.