Dies ist nur ein Konzept, das sicherlich in vielerlei Hinsicht verbessert werden kann, aber nicht so langsam ist, wie ich dachte.
Im Allgemeinen enthält dieser Code einen hexadezimal kodierten Zeitstempel in Millisekunden (mit etwas Hacking ergibt er 12 Ziffern, so dass der Code auch nach 2527-06-24 funktioniert, aber nicht nach 5138-11-16), was bedeutet, dass er sortierbar ist. Es ist nicht so zufällig, es verwendet die MAC-Adresse für die letzten 12 Ziffern. Der 13. Buchstabe ist fest mit 1 kodiert, damit er sortierbar bleibt.
Danach kommen die nächsten 6 Ziffern aus einer halbzufälligen Zeichenfolge, wobei die ersten Ziffern aus der Anzahl der in dieser Millisekunde erzeugten Datensätze stammen und die anderen Ziffern zufällig erzeugt werden. Dieser 6-stellige Teil enthält einen Bindestrich und den hart kodierten Buchstaben "a", um die Datensätze sortierbar zu halten.
Ich weiß, dass man das Verfahren verkürzen und die Leistung verbessern könnte, aber ich bin mit den Ergebnissen zufrieden (außer der MAC-Adresse).
currentNanoseconds = () => {
return nodeMode ? process.hrtime.bigint() : BigInt(Date.now() * 1000000);
}
nodeFindMacAddress = () => {
// Extract MAC address
const interfaces = require('os').networkInterfaces();
let result = null;
for (index in interfaces) {
let entry = interfaces[index];
entry.forEach(item => {
if (item.mac !== '00:00:00:00:00:00') {
result = '-' + item.mac.replace(/:/g, '');
}
});
}
return result;
}
const nodeMode = typeof(process) !== 'undefined';
let macAddress = nodeMode ? nodeFindMacAddress() : '-a52e99ef5efc';
let startTime = currentNanoseconds();
let uuids = []; // Array for storing generated UUIDs, useful for testing
let currentTime = null; // Holds the last value of Date.now(), used as a base for generating the UUID
let timePart = null; // Part of the UUID generated from Date.now()
let counter = 0; // Used for counting records created at certain millisecond
let lastTime = null; // Used for resetting the record counter
const limit = 1000000;
for (let testCounter = 0; testCounter < limit; testCounter++) {
let uuid = testMe();
if (nodeMode || testCounter <= 50) {
uuids.push(uuid);
}
}
const timePassed = Number(currentNanoseconds() - startTime);
if (nodeMode) {
const fs = require('fs');
fs.writeFileSync('temp.txt', JSON.stringify(uuids).replace(/,/g, ',\n'));
} else {
console.log(uuids);
}
console.log({
operationsPerSecond: (1000 * limit / timePassed).toString() + 'm',
nanosecondsPerCycle: timePassed / limit,
milliSecondsPassed: timePassed / 1000000,
microSecondsPassed: timePassed / 1000,
nanosecondsPassed: timePassed
});
function testMe() {
currentTime = Date.now();
let uuid = null; // Function result
if (currentTime !== lastTime) {
// Added a 9 before timestamp, so that the hex-encoded timestamp is 12 digits long. Currently, it is 11 digits long, and it will be until 2527-06-24
// console.log(Date.parse("2527-06-24").toString(16).length)
// Code will stop working on 5138-11-17, because the timestamp will be 15 digits long, and the code only handles up to 14 digit timestamps
// console.log((Date.parse("5138-11-17")).toString().length)
timePart = parseInt(('99999999999999' + currentTime).substr(-14)).toString(16);
timePart = timePart.substr(0, 8) + '-' + timePart.substr(8, 4) + '-1';
counter = 0;
}
randomPart = ('000000' + Math.floor(10 * (counter + Math.random()))).slice(-6);
randomPart = randomPart.substr(0, 3) + '-a' + randomPart.substr(3, 3);
uuid = timePart + randomPart + macAddress;
counter++;
lastTime = currentTime;
return uuid;
}
38 Stimmen
GUIDs, die als Zeichenketten dargestellt werden, sind mindestens 36 und höchstens 38 Zeichen lang und entsprechen dem Muster ^\{?[a-zA-Z0-9]{36}?\}$ und sind daher immer in ASCII.
5 Stimmen
David Bau bietet einen viel besseren Zufallszahlengenerator an, der unter davidbau.com/archives/2010/01/30/ Ich habe einen etwas anderen Ansatz zur Erzeugung von UUIDs unter blogs.cozi.com/tech/2010/04/generating-uuids-in-javascript.html
1 Stimmen
Seltsam, dass das noch niemand erwähnt hat, aber der Vollständigkeit halber: Es gibt eine Fülle von guid-Generatoren auf npm Ich wette, die meisten von ihnen funktionieren auch im Browser.
1 Stimmen
Wenn jemand mehr Optionen wie verschiedene Versionen der uuid und Unterstützung für nicht standardmäßige guids wünscht, können REST-basierte uuid-Generierungsdienste wie diese [ fungenerators.com/api/uuid ] sind ebenfalls eine attraktive Option.
2 Stimmen
Etwa 12 Jahre später mit
BigInt
und ES6-Klassen können auch andere Techniken eingesetzt werden, die Raten von 500.000 uuid/sec ermöglichen. Siehe Referenz5 Stimmen
Comme andere haben erwähnt Wenn Sie nur eine kleine Anzahl von UUIDs in einem Browser erzeugen, verwenden Sie einfach
URL.createObjectURL(new Blob()).substr(-36)
. ( Ausgezeichnete Browser-Unterstützung ). (Um Speicherlecks zu vermeiden, URL.revokeObjectURL(url) aufrufen )1 Stimmen
Wenn Sie ein unternehmenskritisches Problem haben, schreiben Sie besser einen Endpunkt, der mit Pyhton geschrieben wurde, und rufen ihn auf. Weil es so implementiert ist, wie unter datatracker.ietf.org/doc/html/rfc4122.html