What would be a good algorithm for taking a timestamp that contains year, month, day, hour, minute, second and convert it into a 7 digit or less(but consistent) alphanumeric representation. The alphanumeric representation won't distinguish between upper and lower case letters.
Let's do some maths
You can use 7 alphanumeric digits. Each alphanumeric digit take a value from 36 possible different values (26 letters, 10 decimal digits) So we have 36^7 different values, that is 78364164096.
Now we compute the number of different values needed to represent a given timestamp in one year. To simplify things a bit we will allow some values that will never happen (ex: 31th november).
Thus, we have
month: 12 -> coded from 0 to 11
day: 31 -> coded from 0 to 30
hour: 24
minute: 60
second: 60
which gives use 32140800 different possibilites
We now divide 78364164096 / 32140800 which is ~2438, thus we will give an enumeration of timestamps from 00:00 jan 1 0000 to 23:59 dec 31 2437
The encoding is then
X = second + minute*60 + hour*60*60 +
day*60*60*24 + month*60*60*24*31 +
year*60*60*24*31*12
And the decoding is
second = X mod 60
minute = (X div 60) mod 60
hour = (X div 60*60) mod 24
day = (X div 60*60*24) mod 31
month = (X div 60*60*24*31) mod 12
year = X div 60*60*24*31*12
Let's look at an example:
Suppose you want to encode the date december 20, 1998, 05:33:12 So you would have
second: 12
minute: 33
hour: 5
day: 19 -> note that we encode days in the range 0..31
month: 11 -> note that we conde months in the range 0..11
year: 1998
So we compute:
X = 12 + 33*60 + 5*60*60 +
19*60*60*24 + 11*60*60*24*31 +
1998*60*60*24*31*12
That is, X = 12 + 1980 + 18000 + 1641600 + 29462400 + 64217318400 = 64248442392
And now we decode it
second = 64248442392 mod 60 = 12
minute = (64248442392 div 60) mod 60 = 33
hour = (64248442392 div 60*60) mod 24 = 5
day = (64248442392 div 60*60*24) mod 31 = 19
month = (64248442392 div 60*60*24*31) mod 12 = 11
year = 64248442392 div 60*60*24*31*12 = 1998
Consider a higher than decimal numeral system. For example, the hexadecimal numeral system is base-16. Let's say in our new numeral system, we have digits 0-9, the lower-case alphabet (a-z) and the upper case alphabet (A-Z). This gives us 62 possible digits, so we can use a base-62 numeral system. Here's some Javascript code to do the conversion -
function createConverter() {
var charRange = (start, end) => Array.from(Array(end-start),
(v, i) => String.fromCharCode(i + start))
var digits = charRange(48, 48+10) // 0 to 9
.concat(charRange(97, 97+26)) // a to b
.concat(charRange(65, 65+26)) // A to B
var base = digits.length
return function(decimal) {
var result = ""
while (decimal >= base) {
result = digits[decimal % base] + result
decimal = parseInt(decimal / base)
}
result = digits[decimal] + result
return result
}
}
var convert = createConverter()
convert(parseInt(Date.now() / 1000)) // returns a 6-digit alphanumeric string
charRange
is just a utility arrow function to create a range of characters from ASCII codes
digits
represents all the valid digits in our numeral system. You can add more valid digits (like special chars) to this list
base
is the number (in decimal) of available digits
Output encoded in this base-62 numeral system will stay 6 digits long for more than 1,700 years.
EDIT: Realized Date.now() returns timestamp in milliseconds not seconds, so I've updated my answer to reflect that
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With