Skip to content

Instantly share code, notes, and snippets.

@astatide
Last active March 8, 2019 23:06
Show Gist options
  • Select an option

  • Save astatide/393673ec1525a0729706498d2a4a9a19 to your computer and use it in GitHub Desktop.

Select an option

Save astatide/393673ec1525a0729706498d2a4a9a19 to your computer and use it in GitHub Desktop.
// By Audrey Pratt, care of Cray
// Load up the random module. We need randomness!
use Random;
// Chapel seems to just seed with the timer, so can we pull from the entropy source?
use IO;
// (turns out the answer is yes)
class UDevRandomHandler {
// Swank! This pulls in a bit stream from the entropy source woooooo.
var Entropy = open('/dev/urandom', iomode.r);
var EntropyStream = Entropy.reader();
proc getrandbits(n: int) {
// This is a function similar to the getrandbits in python; it just
// returns a variable containing random bits.
var x: int;
this.EntropyStream.readbits(x, n);
return x;
}
proc returnRNG() {
var RandomNumberGenerator = makeRandomStream(int, seed=this.seed());
}
proc seed() {
var x: int;
return this.EntropyStream.readbits(x, 64);
}
}
class UUID {
// This is a generic class which will be able to output a UUID4 compliant ID
// (I mean, that's the goal, anyway; who knows if I'm doing it right).
// We want our random stuff, so.
var entropySource = new owned UDevRandomHandler();
var remainder: [0..#2] string;
// We want an array to store stuff into.
var uuid_int_rep: [1..16] uint(8);
proc pull_random_data() {
forall i in 1..16 do {
// Just call the appropriate function on the entropy source.
this.uuid_int_rep[i] = abs(this.entropySource.getrandbits(8)) : uint(8);
}
}
proc convert_to_uuid4() {
// Not entirely certain this is correct.
this.uuid_int_rep[7] |= 64;
this.uuid_int_rep[9] |= 2;
}
// This works! Assumes... I think little endian? Big stuff on the left.
// Whatever, I don't have a CS degree, it's fine. We'll sort it later.
proc convert_to_hex(x: uint) {
var result: uint;
// Can I make this global?
//var remainder: [0..#2] string;
const hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
// We have 8 bits of data; we need to split this into 4 bits and calculate
// appropriately.
// first, clear out the last four bits by ANDing them a number that is
// 1 everywhere you don't want cleared, then doing a bit shift.
this.remainder[0] = hex[(((x & 240) >> 4)+1): int];
// now, clear out the first 4 bits. No need to bit shift
this.remainder[1] = hex[((x & 15)+1): int];
return this.remainder;
}
proc UUID4() {
// Currently I can't be bothered to support custom data. Whatever.
// I'm sure there's a more elegant solution for this, but this is just
// proof of concept.
var r_uuid: string;
this.pull_random_data();
this.convert_to_uuid4();
for i in 1..16 do {
for j in this.convert_to_hex(this.uuid_int_rep[i]) {
r_uuid += j;
}
}
r_uuid = r_uuid[1..8] + '-' + r_uuid[9..12] + '-' + r_uuid[13..16] +
'-' + r_uuid[17..20] + '-' + r_uuid[21..32];
return r_uuid;
}
}
var uuid = new owned UUID();
uuid.UUID4();
writeln(uuid.UUID4());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment