c#缩短查询字符串参数

时间:2013-11-07 16:05:36

标签: c# url-shortener

我需要将一个URL作为参数传递到我的查询字符串中,因为URL可能很长我需要在传递时缩短URL,然后才能在服务器端解密它们。

我尝试传递的网址包含敏感信息,因此不需要字符串加密技术,我只是想将长字符串转换为短字符串并能够重新构建它回到一个字符串。

我已经尝试过AES加密,但它的工作原理有时会产生的字符串长度超过URL值。

到目前为止我尝试过的例子:

private static byte[] key = { 252, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 };
private static byte[] vector = { 152, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 };
private ICryptoTransform encryptor, decryptor;
private UTF8Encoding encoder;

public SimpleAES()
{
    RijndaelManaged rm = new RijndaelManaged();
    encryptor = rm.CreateEncryptor(key, vector);
    decryptor = rm.CreateDecryptor(key, vector);
    encoder = new UTF8Encoding();
}

public string Encrypt(string unencrypted)
{
    return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));
}

public string Decrypt(string encrypted)
{
    return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
}

public string EncryptToUrl(string unencrypted)
{ 
    return HttpUtility.UrlEncode(Encrypt(unencrypted));
}

public string DecryptFromUrl(string encrypted)
{
    return Decrypt(HttpUtility.UrlDecode(encrypted));
}

public byte[] Encrypt(byte[] buffer)
{
    return Transform(buffer, encryptor);
}

public byte[] Decrypt(byte[] buffer)
{
    return Transform(buffer, decryptor);
}

protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
    MemoryStream stream = new MemoryStream();
    using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
    {
        cs.Write(buffer, 0, buffer.Length);
    }
    return stream.ToArray();
}

示例测试:

string unencrypted = "/exampleurl/this_is_a_long_string_the_length_of_this_url_is_112_charachters_/this_string_needs_to_be-shortened/"; 

var result = EncryptToUrl(unencrypted);    
"MHMyQdwbJpw8ah%2fbhAr2eJwTFa%2fyupemjuOVcBJmxTIdzcR0PZKCNSa5Fvi7kNrY3Kxlk5KWqAAEspWVtJfNjwwPs%2bCDGpC9Fn8CeGezWhXEbLT6CST2v%2fKpvptHVi3fBYSk1w3q1FYMx3C5DdKueQ%3d%3d" 

实际的字符串是112个字符长,结果是165个字符长。

2 个答案:

答案 0 :(得分:3)

以下代码是here的逐字记录。我复制了这个,因为问题不是重复,但答案解决了这个问题带来的问题。当您致电Zip时,如果您计划将其包含在网址或其他内容中,则需要对结果进行base64编码以使其对浏览器友好。

public static void CopyTo(Stream src, Stream dest) {
    byte[] bytes = new byte[4096];

    int cnt;

    while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
        dest.Write(bytes, 0, cnt);
    }
}

public static byte[] Zip(string str) {
    var bytes = Encoding.UTF8.GetBytes(str);

    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
            //msi.CopyTo(gs);
            CopyTo(msi, gs);
        }

        return mso.ToArray();
    }
}

public static string Unzip(byte[] bytes) {
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
            //gs.CopyTo(mso);
            CopyTo(gs, mso);
        }

        return Encoding.UTF8.GetString(mso.ToArray());
    }
}

static void Main(string[] args) {
    byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
    string r2 = Unzip(r1);
}

答案 1 :(得分:0)

这可能听起来很奇怪,但您可以将查询字符串存储在数据库中并通过某些主键引用它吗?这可能类似于使用某些第三方URL缩短服务。