C# 如何压缩随机字符串?

C# 如何压缩随机字符串?,c#,.net,string,compression,C#,.net,String,Compression,我正在开发一个基于RSA非对称算法的加密应用程序。 它生成一个密钥对,用户必须保留它。 由于密钥对是长随机字符串,我想创建一个函数,让我能够基于模式压缩生成的长随机字符串(密钥对) (例如,函数获取包含100个字符的字符串并返回包含30个字符的字符串) 因此,当用户输入压缩字符串时,我可以根据我使用的压缩模式重新生成密钥对 但是有人告诉我,压缩随机的东西是不可能的,因为它们是随机的 你的想法是什么? 有没有办法做到这一点 感谢不可能压缩(几乎任何)随机数据。学习一点信息论、熵、压缩是如何工作的以

我正在开发一个基于RSA非对称算法的加密应用程序。 它生成一个密钥对,用户必须保留它。 由于密钥对是长随机字符串,我想创建一个函数,让我能够基于模式压缩生成的长随机字符串(密钥对)

(例如,函数获取包含100个字符的字符串并返回包含30个字符的字符串)

因此,当用户输入压缩字符串时,我可以根据我使用的压缩模式重新生成密钥对

但是有人告诉我,压缩随机的东西是不可能的,因为它们是随机的

你的想法是什么? 有没有办法做到这一点


感谢

不可能压缩(几乎任何)随机数据。学习一点信息论、熵、压缩是如何工作的以及鸽子洞原理将使这一点非常清楚

这条规则的一个例外是,如果“随机字符串”是指“以可压缩形式表示的随机数据,如十六进制”。在这种情况下,您可以压缩字符串,或者(更好的选择)简单地将字节编码为base 64,以使其更短。例如

// base 16, 50 random bytes (length 100)
be01a140ac0e6f560b1f0e4a9e5ab00ef73397a1fe25c7ea0026b47c213c863f88256a0c2b545463116276583401598a0c36
// base 64, same 50 random bytes (length 68)
vgGhQKwOb1YLHw5KnlqwDvczl6H+JcfqACa0fCE8hj+IJWoMK1RUYxFidlg0AVmKDDY=

您可以为用户提供一个较短的散列或指纹值(例如,最后的x字节)。然后,通过将完整密钥和散列存储在某个位置,您可以在他们给您散列时给他们密钥。你必须让这个散列足够长,以确保安全性不被破坏。取决于您的应用程序,这可能无法达到目的,因为散列必须与密钥一样长,或者可能不是问题。

不可能压缩(几乎任何)随机数据。学习一点信息论、熵、压缩是如何工作的以及鸽子洞原理将使这一点非常清楚

这条规则的一个例外是,如果“随机字符串”是指“以可压缩形式表示的随机数据,如十六进制”。在这种情况下,您可以压缩字符串,或者(更好的选择)简单地将字节编码为base 64,以使其更短。例如

// base 16, 50 random bytes (length 100)
be01a140ac0e6f560b1f0e4a9e5ab00ef73397a1fe25c7ea0026b47c213c863f88256a0c2b545463116276583401598a0c36
// base 64, same 50 random bytes (length 68)
vgGhQKwOb1YLHw5KnlqwDvczl6H+JcfqACa0fCE8hj+IJWoMK1RUYxFidlg0AVmKDDY=

您可以为用户提供一个较短的散列或指纹值(例如,最后的x字节)。然后,通过将完整密钥和散列存储在某个位置,您可以在他们给您散列时给他们密钥。你必须让这个散列足够长,以确保安全性不被破坏。取决于您的应用程序,这可能无法达到目的,因为散列必须与密钥一样长,或者它可能不是问题。

尝试使用gzip压缩,看看它是否有帮助。

尝试使用gzip压缩,看看它是否有帮助

public static string ZipStr(String str)
{
    using (MemoryStream output = new MemoryStream())
    {
        using (DeflateStream gzip = 
          new DeflateStream(output, CompressionMode.Compress))
        {
            using (StreamWriter writer = 
              new StreamWriter(gzip, System.Text.Encoding.UTF8))
            {
                writer.Write(str);           
            }
        }

        return Convert.ToBase64String(output.ToArray());
    }
}

public static string UnZipStr(string base64)
{
    byte[] input = Convert.FromBase64String(base64);

    using (MemoryStream inputStream = new MemoryStream(input))
    {
        using (DeflateStream gzip = 
          new DeflateStream(inputStream, CompressionMode.Decompress))
        {
            using (StreamReader reader = 
              new StreamReader(gzip, System.Text.Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
    }
}
考虑到这根本不需要更短。。。取决于字符串的内容


考虑到这根本不需要更短。。。取决于字符串的内容。

此人是对的。你应该阅读信息论和熵。如果它是随机的,那么你就有机会随机压缩它!最简单的答案是试着压缩它们,看看你得到了什么,看它是否足够好。需要注意的是,压缩算法通常产生二进制输出,而不是字符串。您可以使用BASE64编码将二进制转换为字符串,但这会导致25%的通货膨胀惩罚(IIRC)。不过,你可能会得到更短的字符串,这取决于它的内容。我不是密码专家,但你所做的将使压缩从100个字符的密钥变为30个字符的密钥。若你们依靠的是不知道你们的“功能”的攻击者,那个么这是行不通的:一些数据是可压缩的,另一些则是不可压缩的。你不能期望每次都有一定程度的压力。那个人是对的。你应该阅读信息论和熵。如果它是随机的,那么你就有机会随机压缩它!最简单的答案是试着压缩它们,看看你得到了什么,看它是否足够好。需要注意的是,压缩算法通常产生二进制输出,而不是字符串。您可以使用BASE64编码将二进制转换为字符串,但这会导致25%的通货膨胀惩罚(IIRC)。不过,你可能会得到更短的字符串,这取决于它的内容。我不是密码专家,但你所做的将使压缩从100个字符的密钥变为30个字符的密钥。若你们依靠的是不知道你们的“功能”的攻击者,那个么这是行不通的:一些数据是可压缩的,另一些则是不可压缩的。您不能期望每次都有一定程度的压缩。这似乎确实是一种更好、更安全的工作方式,甚至可能将它们与GUID关联,而不是与密钥哈希关联。@woutervs可能是的,但GUID不是一种安全的东西,但不是加密安全的。生成适当长度的安全伪随机数也会起作用。是的,但我纯粹是针对将其存储在某处的事情,在这种情况下,我认为GUID可能更适合引用实际密钥。据我所知,这与安全无关。当然,从客户机到客户机的密钥传输应该是安全的。(例如,通过使用传输/消息安全性的WCF)。这似乎确实是更好、更安全的工作方式,甚至可能将它们与GUID关联,而不是与密钥哈希关联。@woutervs可能是,但GUID不是一种安全的东西,但不是加密安全的。生成适当长度的安全伪随机数也会起作用。是的,但我纯粹是针对将其存储在某处的事情,在这种情况下,我认为GUID可能更适合引用实际密钥。据我所知,这与安全无关。当然,从客户机到客户机的密钥传输应该是安全的。(例如,通过使用传输/消息安全性的WCF)。