C# Console.WriteLine在大量二进制零后不显示行
这个程序永远不会打印出测试,除非我在它上面设置了一个断点,并跳过我自己。我不明白发生了什么事。谢谢你的帮助C# Console.WriteLine在大量二进制零后不显示行,c#,debugging,C#,Debugging,这个程序永远不会打印出测试,除非我在它上面设置了一个断点,并跳过我自己。我不明白发生了什么事。谢谢你的帮助 public partial class Form1 : Form { public Form1() { InitializeComponent(); string testKey = "lkirwf897+22#bbtrm8814z5qq=498j5"; string testIv = "741952hheeyy66#cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string testKey = "lkirwf897+22#bbtrm8814z5qq=498j5";
string testIv = "741952hheeyy66#cs!9hjv887mxx7@8y";
string testValue = "random";
string encryptedText = EncryptRJ256(testKey, testIv, testValue);
string decryptedText = DecryptRJ256(testKey, testIv, encryptedText);
Console.WriteLine("encrypted: " + encryptedText);
Console.WriteLine("decrypted: " + decryptedText);
Console.WriteLine("test");
}
public static string DecryptRJ256(string key, string iv, string text)
{
string sEncryptedString = text;
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.Mode = CipherMode.CBC;
myRijndael.KeySize = 256;
myRijndael.BlockSize = 256;
byte[] keyByte = System.Text.Encoding.ASCII.GetBytes(key);
byte[] IVByte = System.Text.Encoding.ASCII.GetBytes(iv);
ICryptoTransform decryptor = myRijndael.CreateDecryptor(keyByte, IVByte);
byte[] sEncrypted = Convert.FromBase64String(sEncryptedString);
byte[] fromEncrypt = new byte[sEncrypted.Length + 1];
MemoryStream msDecrypt = new MemoryStream(sEncrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt);
}
public static string EncryptRJ256(string key, string iv, string text)
{
string sToEncrypt = text;
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.Mode = CipherMode.CBC;
myRijndael.KeySize = 256;
myRijndael.BlockSize = 256;
byte[] keyByte = Encoding.ASCII.GetBytes(key);
byte[] IVByte = Encoding.ASCII.GetBytes(iv);
ICryptoTransform encryptor = myRijndael.CreateEncryptor(keyByte, IVByte);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
byte[] toEncrypt = System.Text.Encoding.ASCII.GetBytes(sToEncrypt);
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();
byte[] encrypted = msEncrypt.ToArray();
return Convert.ToBase64String(encrypted);
}
}
编辑:
已尝试调试.WriteLine
Debug.WriteLine("encrypted: " + encryptedText);
Debug.WriteLine("decrypted: " + decryptedText);
Debug.WriteLine("test");
输出:
加密:T4hdAcpP5MROmKLeziLvl7couD0o+6EuB/Kx29RPm9w=
解密:随机测试
不确定为什么不打印行终止符。虽然这对我在Linux上使用Mono有效,但我确实注意到decryptedText有33个字符长——它由字符“r”、“a”、“n”、“d”、“o”、“m”和27个NUL字符组成。我之前推测填充字节可能未初始化,但从代码看,它似乎定义得很好。我推测VisualStudio中的控制台输出窗口会将NUL字符解释为输出的结尾,从而停止打印之后的任何内容,包括WriteLine中的行终止符和测试字符串。我这里没有Visual Studio来测试它,但我认为您应该能够很容易地验证或反驳它。虽然这对我在Linux上使用Mono是有效的,但我确实注意到decryptedText有33个字符长——它由字符“r”、“a”、“n”、“d”、“o”、“m”和27个NUL字符组成。我之前推测填充字节可能未初始化,但从代码看,它似乎定义得很好。我推测VisualStudio中的控制台输出窗口会将NUL字符解释为输出的结尾,从而停止打印之后的任何内容,包括WriteLine中的行终止符和测试字符串。我这里没有Visual Studio来测试它,但我认为您应该能够很容易地验证或反驳这一点。您的加密/解密代码中有一个问题:因为您使用的是PaddingMode。零,解密后,您无法说出原始数据的结束位置,并且您会收到“random”后跟零字节。如果您切换到例如PaddingMode.PKCS7,并正确使用CryptoStream.Read调用的返回值,您将只收到原始文本,即“random”:
var decryptedSize = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt, 0, decryptedSize);
尽管我认为将NUL字节写入控制台应该不会有问题,但我肯定会首先尝试删除它们,尤其是当看到这种奇怪的行为时。加密/解密代码中有一个问题:因为您使用的是PaddingMode.zero,在解密之后,您无法说出原始数据的结束位置,您将收到“random”,后跟零字节。如果您切换到例如PaddingMode.PKCS7,并正确使用CryptoStream.Read调用的返回值,您将只收到原始文本,即“random”:
var decryptedSize = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt, 0, decryptedSize);
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.BlockSize = 256;
尽管我认为将NUL字节写入控制台应该不会有问题,但我肯定会首先尝试删除它们,尤其是当看到这种奇怪的行为时
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.BlockSize = 256;
这就是问题的根源,您加密的数据被填充为零,以获得32字节32 x 8=256的倍数的块大小。在解密后的值中返回这些二进制零。它们的棘手之处在于调试器无法显示它们。这是okayish,您希望值通过ASCII进行往返,您可以在解密后再次删除零。解密代码也需要一些工作,您对解密数据的大小假设太多。修正:
MemoryStream fromEncrypt = new MemoryStream();
MemoryStream msDecrypt = new MemoryStream(sEncrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
byte[] buffer = new byte[4096];
for (; ; ) {
int len = csDecrypt.Read(buffer, 0, buffer.Length);
if (len == 0) break;
fromEncrypt.Write(buffer, 0, len);
}
var result = Encoding.ASCII.GetString(fromEncrypt.GetBuffer(), 0, (int)fromEncrypt.Length);
return result.Trim('\0');
顺便说一句,您应该处理流,使用using语句
这就是问题的根源,您加密的数据被填充为零,以获得32字节32 x 8=256的倍数的块大小。在解密后的值中返回这些二进制零。它们的棘手之处在于调试器无法显示它们。这是okayish,您希望值通过ASCII进行往返,您可以在解密后再次删除零。解密代码也需要一些工作,您对解密数据的大小假设太多。修正:
MemoryStream fromEncrypt = new MemoryStream();
MemoryStream msDecrypt = new MemoryStream(sEncrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
byte[] buffer = new byte[4096];
for (; ; ) {
int len = csDecrypt.Read(buffer, 0, buffer.Length);
if (len == 0) break;
fromEncrypt.Write(buffer, 0, len);
}
var result = Encoding.ASCII.GetString(fromEncrypt.GetBuffer(), 0, (int)fromEncrypt.Length);
return result.Trim('\0');
顺便说一句,您应该处理流,使用using语句。有什么东西被打印出来了吗?是的。打印的最后一行是解密的那一行。为什么这会从表单继承?您可能想尝试创建控制台应用程序,而不是Windows窗体应用程序…@Ben调试winforms应用程序时,我只是将控制台用作输出。您确定没有生成错误吗?IMO最可能的原因是,在您添加该行之前,它仍在运行最新版本的exe…是否打印了任何内容?是的。打印的最后一行是解密的那一行。为什么这会从表单继承?您可能想尝试创建控制台应用程序,而不是Windows窗体应用程序…@Ben调试winforms应用程序时,我只是将控制台用作输出。您确定没有生成错误吗?IMO最可能的原因是,在添加该行之前,它仍在运行最新版本的exe。。。