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