使用嵌入的日期时间生成URL友好的唯一字符串

时间:2011-06-17 08:42:12

标签: c#

我个人厌倦了为我的网络项目重新实现“票证”机制,以进行一些一次性操作,如帐户激活或密码重置。我知道这很简单,但它要求我保留(并坚持!)两个数据:票证本身和到期日期。

所以我有这个想法,生成一个带有嵌入式日期时间(到期日期)的唯一字符串,我们可以在收到url-request时检查它。

我从这开始:

var clearTicket = Convert.ToInt64(expiration.ToString("yyyyMMddhhmm")).ToString("x12") + key.ToString("N");

但我希望它更紧凑。我认为是BaseXX的东西。 任何想法如何有效地实现这种编码/解码(考虑url-safe charset)?

3 个答案:

答案 0 :(得分:2)

我花了一些时间,所以我希望它有所帮助:

首先,你应该从“yyyyMMddhhmm”减去200000000000,因为你实际上不需要接下来88年的前两位数。

以下是仅使用URL安全字符对Base64进行编码和解码的实现 如果您有任何疑问,请随时提出。

public string Base64Encode (Int64 Number)
{
    string HelpString = "";
    if (Number >= 64)
    {
        HelpString = Base64Encode(Number / 64);
    }
    return (HelpString += Base64EncodeHelper(Number % 64));
}

public string Base64EncodeHelper(Int64 Number)
{
    string HelpString = "";
    Number += 65;
    if ((Number >= 65 && Number <= 90) || (Number >= 97 && Number <= 122))  // 0 - 25 and 32 - 57
    {
        HelpString = Convert.ToString((char)Number);
    }
    else if (Number >= 91 && Number <= 96)                                  // 26 - 31
    {
        HelpString = Convert.ToString((char)(Number - 43));
    }
    else if (Number >= 123 && Number <= 126)                                // 58 - 61
    {
        HelpString = Convert.ToString((char)(Number - 69));
    }
    else if (Number == 127)                                                 // 62
    {
        HelpString = "-";
    }
    else                                                                    // 63
    {
        HelpString = "_";
    }
    return (HelpString);
}

public Int64 Base64Decode(string Encoded)
{
    Int64 Result = 0, HelpInt = 0;
    int i = Encoded.Length - 1;
    foreach (char Character in Encoded)
    {
        int CharInInt = (int)Character;
        if (Character == '_')
        {
            HelpInt = 63;
        }
        else if (Character == '-')
        {
            HelpInt = 62;
        }
        else if (((CharInInt + 69) >= 123) && ((CharInInt + 69) <= 126))
        {
            HelpInt = CharInInt + 4;
        }
            else if (((CharInInt + 43) >= 91) && ((CharInInt + 43) <= 96))
        {
            HelpInt = CharInInt - 22;
        }
        else
        {
             HelpInt = CharInInt - 65;
        }
        Result += Convert.ToInt64((Math.Pow(64, Convert.ToDouble(i))) * HelpInt);
        i--;
    }
    return Result;
}

答案 1 :(得分:0)

您可以像这样扩展字符串:

public static string ToURLParameter(this string text)
{
    if (String.IsNullOrEmpty(text)) return "";

    // to lowercase, trim extra spaces
    text = text.Trim();

    var len = text.Length;
    var sb = new StringBuilder(len);
    bool prevdash = false;
    char c;

    //
    text = text.Replace('Å', 'A');
    text = text.Replace('å', 'a');
    text = text.Replace('Ä', 'A');
    text = text.Replace('ä', 'a');
    text = text.Replace('Ö', 'O');
    text = text.Replace('ö', 'o');

    for (int i = 0; i < text.Length; i++)
    {
        c = text[i];
        if (c == ' ' || c == ',' || c == '.' || c == '/' || c == '\\' || c == '-')
        {
            if (!prevdash)
            {
                sb.Append('-');
                prevdash = true;
            }
        }
        else if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))
        {
            sb.Append(c);
            prevdash = false;
        }
        if (i == 80) break;
    }

    text = sb.ToString();
    // remove trailing dash, if there is one
    if (text.EndsWith("-"))
        text = text.Substring(0, text.Length - 1);

    return text;
}

然后你可以在任何字符串变量上使用它:

string something = "asdfljasdklf";

<%= something.ToUrlParameter() %>

答案 2 :(得分:0)

我终于使用这些答案中描述的技术创建了一个解决方案:

Compressing big number (or string) to small value

How do you convert Byte Array to Hexadecimal String, and vice versa?

效果很好!

谢谢大家的帮助!