Convert DateTime to shortest possible version number (for url)
-
29-10-2019 - |
Question
Challenge: convert a 'modified date' DateTime
of an image file to a version number / string suitable for maintaining uniqueness in a url, so each modification of the image generates a unique url, the version number/string to be as short as possible.
The shortness of code is secondary to the shortness of number/string Apologies if this does not really qualify for code-golf status :-)
Requirements
- C#, .Net framework v4
- output must be valid characters for a folder-name in a url.
- DateTime precision can be reduced to nearest minute.
EDIT: this is not entirely theoretical / Puzzle, so I guess I'd rather keep it here than on code-golf stack exchange?
Solution
Use the DateTime.Ticks
property and then convert it to a base 36 number. It'll be very short and usable on a URL.
Here's a class for converting to/from Base 36:
http://www.codeproject.com/KB/cs/base36.aspx
You could also use base 62, but not base64 since one of the extra digits in base 64 beyond numbers and letters is +
which needs to be url encoded and you said you wanted to avoid that.
OTHER TIPS
Ok, combining answers and comments I've come up with the following.
Note: removal of zero padding bytes, and starting date difference from the start of the project to reduce the size of numbers.
public static string GetVersion(DateTime dateTime)
{
System.TimeSpan timeDifference = dateTime - new DateTime(2010, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long min = System.Convert.ToInt64(timeDifference.TotalMinutes);
return EncodeTo64Url(min);
}
public static string EncodeTo64Url(long toEncode)
{
string returnValue = EncodeTo64(toEncode);
// returnValue is base64 = may contain a-z, A-Z, 0-9, +, /, and =.
// the = at the end is just a filler, can remove
// then convert the + and / to "base64url" equivalent
//
returnValue = returnValue.TrimEnd(new char[] { '=' });
returnValue = returnValue.Replace("+", "-");
returnValue = returnValue.Replace("/", "_");
return returnValue;
}
public static string EncodeTo64(long toEncode)
{
byte[] toEncodeAsBytes = System.BitConverter.GetBytes(toEncode);
if (BitConverter.IsLittleEndian)
Array.Reverse(toEncodeAsBytes);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes.SkipWhile(b=>b==0).ToArray());
return returnValue;
}