4

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?

Myster
  • 17,704
  • 13
  • 64
  • 93
  • 1
    Simple, use the UNIX Epoch as given here: http://stackoverflow.com/questions/906034/calculating-future-epoch-time-in-c – Candide Sep 12 '11 at 03:37

2 Answers2

3

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.

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
  • 1
    He could use Base64 and replace the `/` and the `+` with (for example) `-` and `_`. – xanatos Sep 12 '11 at 05:23
  • @xanatos, yes, that's easier than creating a base62 converter and smaller than using base36. – Samuel Neff Sep 12 '11 at 17:52
  • 1
    6 characters of base 36 can encode all Unix epoch times for the next 27 years. There's little practical advantage to base 62 unless you have times in the distant future or need better resolution than a second. – mob Sep 15 '11 at 20:18
2

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;
    }
Myster
  • 17,704
  • 13
  • 64
  • 93