C# 使用嵌入的datetime生成URL友好的唯一字符串

C# 使用嵌入的datetime生成URL友好的唯一字符串,c#,C#,就我个人而言,我已经厌倦了为我的web项目重新实现“一张票”机制,以实现一些一次性操作,如帐户激活或密码重置。我知道这很简单,但它需要我保留(并保持!)两条数据:一张票证本身和一个过期日期 所以我有这个想法,生成一个嵌入了datetime(过期日期)的唯一字符串,我们可以在接收时将其作为url请求的一部分进行检查 我从以下几点开始: var clearTicket=Convert.ToInt64(expiration.ToString(“yyyyMMddhhmm”).ToString(“x12”

就我个人而言,我已经厌倦了为我的web项目重新实现“一张票”机制,以实现一些一次性操作,如帐户激活或密码重置。我知道这很简单,但它需要我保留(并保持!)两条数据:一张票证本身和一个过期日期

所以我有这个想法,生成一个嵌入了datetime(过期日期)的唯一字符串,我们可以在接收时将其作为url请求的一部分进行检查

我从以下几点开始:

var clearTicket=Convert.ToInt64(expiration.ToString(“yyyyMMddhhmm”).ToString(“x12”)+key.ToString(“N”);
但我希望它更紧凑。我想是有点卑鄙。
如何有效地实现这种编码/解码(考虑url安全字符集)?

您可以这样扩展字符串:

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;
}
公共静态字符串ToURLParameter(此字符串文本)
{
if(String.IsNullOrEmpty(text))返回“”;
//若要使用小写,请修剪额外的空格
text=text.Trim();
var len=text.Length;
var sb=新的StringBuilder(len);
bool-prevdash=false;
字符c;
//
text=text.Replace('Å','A');
text=text.Replace('å','a');
text=text.Replace('Ä','A');
text=text.Replace('a','a');
text=text.Replace('Ö','O');
text=text.Replace('ö','o');
for(int i=0;ielse if((c>='a'&&c='0'&&c='a'&&c这花了我一些时间,所以我希望它能帮助:

首先,您应该从“yyyyMMddhhmm”中减去200000000,因为在接下来的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;
}
公共字符串Base64Encode(Int64编号)
{
字符串HelpString=“”;
如果(数字>=64)
{
HelpString=Base64Encode(数字/64);
}
返回(HelpString+=Base64EncodeHelper(编号%64));
}
公共字符串Base64EncodeHelper(Int64编号)
{
字符串HelpString=“”;
数字+=65;

如果((Number>=65&&Number=97&&Number=91&&Number=123&&Number=123)&((CharInInt+69)=91)&((CharInInt+43)我最终使用这些答案中描述的技术创建了一个解决方案:

很好


谢谢大家的帮助!

如果您使用asp.net mvc,您可以在url.Lasse Edsvik中的值中使用带有约束的url路由-但我必须在稍后将字符串作为参数接收时对其进行解码。此外,我无法确定它在TourParameter()之后是否保持唯一性转换。看起来不太安全…更改过期日期确实很容易,但它不会以任何方式影响安全性。此字符串将存储在数据库中,事实上,我将通过它搜索用户配置文件,然后我将提取日期时间以查看令牌是否已过期。谢谢,有趣的方法!你说得对关于一年中的第一个数字,不需要。我现在无法检查,但既然您已经实现了自己的base64,我相信它是url安全的?我已经成功地使用日期和guid的整个十六进制字符串(224位左右)创建了该想法的工作实现但由于规则原因,无法在此发布。我将在周一发布。但我对base64转换不太满意,因此我将尝试您的方法。编码字符串由小写字母[a,z]、大写字母[a,z]、数字[0,9]、“破折号”[-]和下划线[\ux]组成。URL中允许所有这些字符。
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;
}