将 DateTime 转换为尽可能短的版本号(对于 url)

发布于 2024-12-04 08:05:55 字数 323 浏览 0 评论 0原文

挑战:将图像文件的“修改日期”DateTime 转换为适合保持 url 中唯一性的版本号/字符串,因此图像的每次修改都会生成唯一的 url、版本号/字符串尽可能短。

代码的简短程度仅次于数字/字符串的简短程度 如果这并不真正符合代码高尔夫状态,我们深表歉意:-)

要求

  • C#、.Net Framework v4
  • 输出必须是 url 中文件夹名称的有效字符。
  • 日期时间精度可以降低到最接近的分钟。

编辑:这并不完全是理论/谜题,所以我想我宁愿把它留在这里,而不是代码高尔夫堆栈交换?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心作怪 2024-12-11 08:05:55

使用 DateTime.Ticks 属性,然后将其转换为 36 进制数字。它会非常短并且可以在 URL 上使用。

下面是一个用于与 Base 36 进行转换的类:

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

您也可以使用 Base 62,但不能使用 Base64,因为 Base 64 中除数字和字母之外的额外数字之一是 +,需要对其进行 url 编码,并且你说过你想避免这种情况。

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.

蹲在坟头点根烟 2024-12-11 08:05:55

好的,结合答案和评论,我得出了以下内容。
注意:删除零填充字节以及与项目开始时的开始日期差异,以减少数字的大小。

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

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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文