Skip to content

Instantly share code, notes, and snippets.

@perigrin
Created April 9, 2020 17:16
Show Gist options
  • Save perigrin/040f49c012c380979134d02cafac7488 to your computer and use it in GitHub Desktop.
Save perigrin/040f49c012c380979134d02cafac7488 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use 5.10;
use POSIX qw(floor);
use DateTime;
=for example
var generateUUID = (function() {
"use strict";
var a = 0, b = [];
return function() {
var c = (new Date()).getTime() + 0, d = c === a;
a = c;
for (var e = new Array(8), f = 7; 0 <= f; f--) {
e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64);
c = Math.floor(c / 64);
}
c = e.join("");
if (d) {
for (f = 11; 0 <= f && 63 === b[f]; f--) {
b[f] = 0;
}
b[f]++;
} else {
for (f = 0; 12 > f; f++) {
b[f] = Math.floor(64 * Math.random());
}
}
for (f = 0; 12 > f; f++){
c += "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);
}
return c;
};
}()),
generateRowID = function () {
"use strict";
return generateUUID().replace(/_/g, "Z");
};
=cut
sub makeUUIDGenerator {
return sub {
# we have some state we need to keep around between UUID calls
state $last = 0;
state $b = [];
# and we need some output
my $output;
# grab the current time
my $now = DateTime->now()->as_epoch + 0;
# make a copy that we can manipulate
my $count_down = $now;
# now we build half the UUID based on time
my @e;
for (7..0) {
# there is probably a way smarter way to do this
@e[$_] = substr("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz", $count_down % 64, 1);
$count_down = floor($count_down / 64);
}
$output = join '', @e;
# now we build the second half the UUID based on a random string ...
if ($last == $now) { # but if we're trying for a second UUID before the time has changed
# this wraps any character that would overflow the 64 back to 0
for (my $f = 11; $f >= 0 && $b->[$f] == 63; $f--) {
$b->[$f] = 0;
}
# and then just use the previous string and bump every value by 1.
$b->[f]++;
} else {
# otherwise generate a whole new random string for the end
for my $f (0..11) {
$b->[$f] = floor(64 * rand());
}
}
# this loops through @$b and creates appends the UUID elements to the output
for my $f (0..11) {
$output += substr("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz", $b->[$f], 1);
}
# remember when we last ran this
$last = $now;
return $output;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment