Конвертировать DateTime в максимально короткий номер версии (для URL) - PullRequest
2 голосов
/ 12 сентября 2011

Задача: преобразовать «дату изменения» DateTime файла изображения в номер / строку версии, подходящую для поддержания уникальности в URL, поэтому каждая модификация изображения генерирует уникальный URL-адрес, номер / строку версии длякак можно короче.

Недостаток кода является вторичным по отношению к недостатку числа / строки. Извинения, если это на самом деле не соответствует статусу кода-гольфа: -)

Требования

  • C #, .Net framework v4
  • выходные данные должны быть действительными символами для имени папки в URL.
  • Точность DateTime может быть уменьшена до ближайшей минуты.

РЕДАКТИРОВАТЬ: это не совсем теоретическая задача / головоломка, так что, я думаю, я бы предпочел оставить ее здесь, чем на обмене стеками кода-гольфа?

Ответы [ 2 ]

2 голосов
/ 12 сентября 2011

Используйте свойство DateTime.Ticks, а затем преобразуйте его в базовое число 36.Он будет очень коротким и пригодным для использования по URL.

Вот класс для преобразования в / из Base 36:

http://www.codeproject.com/KB/cs/base36.aspx

Вы также можете использовать Base 62, но не base64, поскольку одна из дополнительных цифр в base 64, кроме цифр и букв, - +, которую необходимо кодировать в URL, и вы сказали, что хотите этого избежать.

1 голос
/ 13 сентября 2011

Хорошо, объединяя ответы и комментарии, я придумал следующее.
Примечание: удаление нулевых байтов заполнения и разницы в датах начала с начала проекта для уменьшения размера чисел.

    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;
    }
...