How to extract timestamp from UUID v1 (TimeUUID) using javascript? - node.js

I use Cassandra DB and Helenus module for nodejs to operate with this. I have some rows which contains TimeUUID columns. How to get timestamp from TimeUUID in javascript?

this lib ( UUID_to_Date ) is very simple and fast!! only used native String function.
maybe this Javascript API can help you to convert the UUID to date format,
Javascript is simple language and this simple code can help to writing API for every language.
this API convert UUID v1 to sec from 1970-01-01
all of you need:
get_time_int = function (uuid_str) {
var uuid_arr = uuid_str.split( '-' ),
time_str = [
uuid_arr[ 2 ].substring( 1 ),
uuid_arr[ 1 ],
uuid_arr[ 0 ]
].join( '' );
return parseInt( time_str, 16 );
};
get_date_obj = function (uuid_str) {
var int_time = this.get_time_int( uuid_str ) - 122192928000000000,
int_millisec = Math.floor( int_time / 10000 );
return new Date( int_millisec );
};
Example:
var date_obj = get_date_obj( '8bf1aeb8-6b5b-11e4-95c0-001dba68c1f2' );
date_obj.toLocaleString( );// '11/13/2014, 9:06:06 PM'

You can use the unixTimestampOf or dateOf functions in CQL3, or you can do it yourself, the hard way:
The time is encoded into the top 64 bits of the UUID, but it's interleaved with some other pieces, so it's not super straight forward to extract a time.
If n is the integer representation of the TimeUUID then you can extract the UNIX epoch like this:
n = (value >> 64)
t = 0
t |= (n & 0x0000000000000fff) << 48
t |= (n & 0x00000000ffff0000) << 16
t |= (n & 0xffffffff00000000) >> 32
t -= 122192928000000000
seconds = t/10_000_000
microseconds = (t - seconds * 10_000_000)/10.0
this code is from my Ruby CQL3 driver, cql-rb, and can be found in full here: https://github.com/iconara/cql-rb/blob/master/lib/cql/time_uuid.rb
I used this resource: http://www.famkruithof.net/guid-uuid-timebased.html, and the RFC to implement that code.

Use uuid-time module.
I asked maintainers of uuid module here https://github.com/kelektiv/node-uuid/issues/297 and they pointed me to the uuid-time module https://www.npmjs.com/package/uuid-time

node-uuid module for nodejs contains method for convert uuid v1 to timestamp
Commit with function for extract msecs from uuid v1

Related

How to convert 24 hour format to 12 hour format in groovy [duplicate]

This question already has answers here:
How to convert 24 hr format time in to 12 hr Format?
(16 answers)
Closed 3 years ago.
I'm new to groovy and i want to convert 24 hour format to 12 hour format. What is the code to be used for it? Is there any built-in methods?
I just want groovy code not java one
Kevin's answer is correct, and should get the tick... I only post this as it's slightly shorter
import java.time.*
import static java.time.format.DateTimeFormatter.ofPattern
String time = '13:23:45'
String result = LocalTime.parse(time).format(ofPattern('h:mm:ss a'))
println result
I thought this question is somewhat similar to the How to convert 24 hr format time in to 12 hr Format?. It just that Java and Groovy share a lot of similarities. To point that out, I took Cloud's answer from the mentioned question and converted that to Groovy.
import java.time.LocalTime
import java.time.format.DateTimeFormatter
final String time = "21:49"
String result = LocalTime.parse(time, DateTimeFormatter.ofPattern("HH:mm")).format(DateTimeFormatter.ofPattern("hh:mm a"));
println(result)
If you want to build your own time function you can try to customize the code below.
final String time = "21:49"
final String _24to12( final String input ){
if ( input.indexOf(":") == -1 )
throw ("")
final String []temp = input.split(":")
if ( temp.size() != 2 )
throw ("") // Add your throw code
// This does not support time string with seconds
int h = temp[0] as int // if h or m is not a number then exception
int m = temp[1] as int // java.lang.NumberFormatException will be raised
// that can be cached or just terminate the program
String dn
if ( h < 0 || h > 23 )
throw("") // add your own throw code
// hour can't be less than 0 or larger than 24
if ( m < 0 || m > 59 )
throw("") // add your own throw code
// minutes can't be less than 0 or larger than 60
if ( h == 0 ){
h = 12
dn = "AM"
} else if ( h == 12 ) {
dn = "PM"
} else if ( h > 12 ) {
h = h - 12
dn = "PM"
} else {
dn = "AM"
}
return h.toString() + ":" + m.toString() + " " + dn.toString()
}
println(_24to12(time))

How to create a big list of different UUIDs, efficiently?

I want to generate tickets for an event. I need to generate a lot of them and I decided to have the ticket number as UUIDs. The question is how to generate a big list of UUIDs and it to be different.
I know the easy way to just check every new UUID generated in the already existing list, but this is not very performance friendly. :)
I am using NodeJS with UUID v4.
Thank you!
You could use home-grown UUID function, which is guaranteed to be unique pseudo-random integer in the range [0...2128). Below is one based on Linear Contguential Generator. Constants are taken from here or here. You only need to keep previous number/UUID at hands to generate next one, no need to check because it will be repeated only after full period of 2128.
Code relies on BigInt, tested with node v12
const a = 199967246047888932297834045878657099405n; // should satisfy a % 8n = 5n
const c = 1n; // should be odd
const m = (1n << 128n);
const mask = m - 1n;
function LCG128(state) {
return (BigInt(state) * a + c) & mask; // same as % m
}
q = 7654321n; // seed
q = LCG128(q);
q.toString(16); // first UUID
q = LCG128(q);
q.toString(16); // second UUID
q = LCG128(q);
q.toString(16); // third UUID
UPDATE
Just to be a more philosophical on the issue at hands:
You could consider UUID4 to be black box and trust it - this is what #ChrisWhite proposed
You could consider UUID4 to be black box and distrust it - that is whatyou proposed to check in the list or answer by #KevinPastor
Make your own transparent box which produces numbers in the proper range and be unique - that is my proposal
Beauty of LCG approach is that, given good multiplier and carry, it uniquely and reversable maps range [0...2128) into itself (it could do that for 64bit numbers, with different a, c, or 32bit numbers and so on and so forth). You could even use counter as input starting with 0 up to 2128-1 and it will produce non-repeatable numbers in the same range filling whole [0...2128). So you know that if you either chain it with previous uuid, or use counter, there is 0 chances of collision.
You can create an empty object and every time you generate a UUID, you add an attribute to that object where the key is the generated UUID. When you will generate another UUID, you just have to check if the object attribute is undefined or not to see if it's already used.
const uuids = [];
let uuidUsed = {};
const size = 10;
for (let i = 0; i < size; i++) {
let uuid = uuidv4();
while (uuidUsed[uuid] !== undefined) {
uuid = uuidv4();
}
uuidUsed[uuid] = true;
}
here’s a list of 446,538 IPs formatted in the following way: | id | date | name | uuid | ip |
https://minerlock.com/lock/F50f4b8d8e27e

How to read/write a bigint from buffer in node.js 10?

I see that BigInt is supported in node 10. However, there's no ReadBigInt() functionality in the Buffer class.
Is it possible to somehow go around it? Perhaps read 2 ints, cast them to BigInt, shift the upper one and add them to reconstruct the bigint?
A little late to the party here, but as the BigInt ctor accepts a hex string we can just convert the Buffer to a hex string and pass that in to the BigInt ctor. This also works for numbers > 2 ** 64 and doesn't require any dependencies.
function bufferToBigInt(buffer, start = 0, end = buffer.length) {
const bufferAsHexString = buffer.slice(start, end).toString("hex");
return BigInt(`0x${bufferAsHexString}`};
}
I recently had encountered the need to do this as well, and managed to find this npm library: https://github.com/no2chem/bigint-buffer ( https://www.npmjs.org/package/bigint-buffer ) which can read from a buffer as a BigInt.
Example Usage (reading, there is more examples on the linked github/npm):
const BigIntBuffer = require('bigint-buffer');
let testBuffer = Buffer.alloc(16);
testBuffer[0] = 0xff; // 255
console.log(BigIntBuffer.toBigIntBE(testBuffer));
// -> 338953138925153547590470800371487866880n
That will read the 16byte (128bit) number from the buffer.
If you wish to read only part of it as a BigInt, then slicing the buffer should work.
With Node v12, functions for reading bigint from buffers was added, so if possible, you should try to use Node v12 or later.
But these functions are just pure math based on reading integers from the buffer, so you can pretty much copy them into your Node 10-11 code.
https://github.com/nodejs/node/blob/v12.6.0/lib/internal/buffer.js#L78-L152
So modifying these methods to not be class methods could look something like this
function readBigUInt64LE(buffer, offset = 0) {
const first = buffer[offset];
const last = buffer[offset + 7];
if (first === undefined || last === undefined) {
throw new Error('Out of bounds');
}
const lo = first +
buffer[++offset] * 2 ** 8 +
buffer[++offset] * 2 ** 16 +
buffer[++offset] * 2 ** 24;
const hi = buffer[++offset] +
buffer[++offset] * 2 ** 8 +
buffer[++offset] * 2 ** 16 +
last * 2 ** 24;
return BigInt(lo) + (BigInt(hi) << 32n);
}
EDIT: For anyone else having the same issue, I created a package for this.
https://www.npmjs.com/package/read-bigint
One liner: BigInt('0x'+buffer.toString('hex'))

How to shorten UUID V4 without making it non-unique/guessable

I have to generate unique URL part which will be "unguessable" and "resistant" to brute force attack. It also has to be as short as possible :) and all generated values has to be of same length. I was thinking about using UUID V4 which can be represented by 32 (without hyphens) hex chars de305d5475b4431badb2eb6b9e546014 but it's a bit too long. So my question is how to generate something unqiue, that can be represented with url charcters with same length for each generated value and shorter than 32 chars. (In node.js or pgpsql)
v4() will generate a large number which is translated into a hexadecimal string. In Node.js you can use Buffer to convert the string into a smaller base64 encoding:
import { v4 } from 'uuid';
function getRandomName() {
let hexString = v4();
console.log("hex: ", hexString);
// remove decoration
hexString = hexString.replace(/-/g, "");
let base64String = Buffer.from(hexString, 'hex').toString('base64')
console.log("base64:", base64String);
return base64String;
}
Which produces:
hex: 6fa1ca99-a92b-4d2a-aac2-7c7977119ebc
base64: b6HKmakr
hex: bd23c8fd-0f62-49f4-9e51-8b5c97601a16
base64: vSPI/Q9i
UUID v4 itself does not actually guarantee uniqueness. It's just very, very unlikely that two randomly generated UUIDs will clash. That's why they need to be so long - that reduces the clashing chance.
So you can make it shorter, but the shorter you make it, the more likely that it won't actually be unique. UUID v4 is 128 bit long because that is commonly considered "unique enough".
The short-uuid module does just that.
"Generate and translate standard UUIDs into shorter - or just different - formats and back."
It accepts custom character sets (and offers a few) to translate the UUID to and fro.
You can also base64 the uuid which shortens it a bit to 22. Here's a playground.
It all depends on how guessable/unique it has to be.
My suggestion would be to generate 128 random bits and then encode it using base36. That would give you a "nice" URL and it would be unique and probably unguessable enough.
If you want it even shorter you can use base64, but base64 needs to contain two non alphanumeric characters.
This is a fairly old thread, but I'd like to point out the top answer does not produce the results it claims. It will actually produce strings that are ~32 characters long, but the examples claim 8 characters. If you want more compression convert the uuid to base 90 using this function.
Using Base64 takes 4 characters for every 3 bytes, and Hex (Base16) takes 2 characters for each byte. This means that Base64 will have ~67% better storage size than hex, but if we can increase that character/byte ratio we can get even better compression. Base90 gives ever so slightly more compression because of this.
const hex = "0123456789abcdef";
const base90 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+-./:<=>?#[]^_`{|}~";
/**
* Convers a Base16 (Hex) represented string to a Base 90 String.
* #param {String} number Hex represented string
* #returns A Base90 representation of the hex string
*/
function convertToBase90(number) {
var i,
divide,
newlen,
numberMap = {},
fromBase = hex.length,
toBase = base90.length,
length = number.length,
result = typeof number === "string" ? "" : [];
for (i = 0; i < length; i++) {
numberMap[i] = hex.indexOf(number[i]);
}
do {
divide = 0;
newlen = 0;
for (i = 0; i < length; i++) {
divide = divide * fromBase + numberMap[i];
if (divide >= toBase) {
numberMap[newlen++] = parseInt(divide / toBase, 10);
divide = divide % toBase;
} else if (newlen > 0) {
numberMap[newlen++] = 0;
}
}
length = newlen;
result = base90.slice(divide, divide + 1).concat(result);
} while (newlen !== 0);
return result;
}
/**
* Compresses a UUID String to base 90 resulting in a shorter UUID String
* #param {String} uuid The UUID string to compress
* #returns A compressed UUID String.
*/
function compressUUID(uuid) {
uuid = uuid.replace(/-/g, "");
return convertToBase90(uuid);
}
Over a few million random uuids this generates no duplicates and the following output:
Lengths:
Avg: 19.959995 Max: 20 Min: 17
Examples:
Hex: 68f75ee7-deb6-4c5c-b315-3cc6bd7ca0fd
Base 90: atP!.AcGJh1(eW]1LfAh
Hex: 91fb8316-f033-40d1-974d-20751b831c4e
Base 90: ew-}Kv&nK?y#~xip5/0e
Hex: 4cb167ee-eb4b-4a76-90f2-6ced439d5ca5
Base 90: 7Ng]V/:0$PeS-K?!uTed
UUID is 36 characters long and you can shorten it to 22 characters (~30%) if you want save ability to convert it back and for it to be url safe.
Here is pure node solution for base64 url safe string:
type UUID = string;
type Base64UUID = string;
/**
* Convert uuid to base64url
*
* #example in: `f32a91da-c799-4e13-aa17-8c4d9e0323c9` out: `8yqR2seZThOqF4xNngMjyQ`
*/
export function uuidToBase64(uuid: UUID): Base64UUID {
return Buffer.from(uuid.replace(/-/g, ''), 'hex').toString('base64url');
}
/**
* Convert base64url to uuid
*
* #example in: `8yqR2seZThOqF4xNngMjyQ` out: `f32a91da-c799-4e13-aa17-8c4d9e0323c9`
*/
export function base64toUUID(base64: Base64UUID): UUID {
const hex = Buffer.from(base64, 'base64url').toString('hex');
return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(
12,
16,
)}-${hex.substring(16, 20)}-${hex.substring(20)}`;
}
Test:
import { randomUUID } from "crypto";
// f32a91da-c799-4e13-aa17-8c4d9e0323c9
const uuid = randomUUID();
// 8yqR2seZThOqF4xNngMjyQ
const base64 = uuidToBase64(uuid);
// f32a91da-c799-4e13-aa17-8c4d9e0323c9
const uuidFromBase64 = base64toUUID(base64);

Convert string timer to integer seconds

i'm trying to convert an string like "0:13:30", which consist of h:mm:ss, to an integer which will be an answer of (m*60)+(s), working only with the minutes and seconds in greasemonkey or jscript.
What i curently have is:
var t_str = ''; var t_int =0;
var str1='';var str2='';var t_int1=0;var t_int2=0;
t_str="0:13:30";
alert(t_str);
str1=t_str[4]+t_str[5];
str2=t_str[2]+t_str[3];
t_int1=parseInt (str1);
t_int2=parseInt (str2);
t_int2=t_int2 * 60;
t_int=t_int1+t_int2;
alert(t_int);
I get up to the first alert. how do i get it to assign the values "13" and "30" to str2 and str1? Sorry for a basic question, but im not used to this language :)
var time = t_str.split(":"),
h = 3600 * parseInt(time[0], 10),
m = 60 * parseInt(time[1], 10),
s = parseInt(time[2], 10);
alert(h+m+s);
I assume you are using javascript. If yes, then you can use split() method to split the t_str first and then carry on with your parsing of integers.
`str = t_str.split(":");` //- array of {0,13,30}
and then use this array to access your numbers.

Resources