compression/decompression 的 c# 问题
c# problem with compression/decompression
我是一名计算机学徒,3 个月前我们开始学习 C#。我只是请你帮忙,因为我必须执行一个 "Whatsapp" 类型的项目。目标是加密和压缩消息。我可以加密消息并压缩它,但我不能解压缩它。我有一个 "System.IO.InvalidDataException: 'The magic number in the GZip header is not correct. Make sure that your passage takes place in a GZip stream" 类型的错误。我将代码复制到另一个主题并尝试将其适配到我的程序中,但无济于事。感谢您的理解。
我的项目是用 Windows 表格制作的。评论是法语的(因为我是法国人,我的老师要求法语评论)但我认为我的代码很容易理解。
编辑:问题出现在我的方法 "Decompression" 第 139 行
post 我说的是:
Compression/Decompression string with C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;
namespace ChatApp
{
public partial class Form1 : Form
{
private static string strPath = @"..\..\..\messages\communication.txt";
const byte byteNbrMsg = 2;
private static short shrtNbrRandom = 947;
public Form1()
{
InitializeComponent();
byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
string r2 = Unzip(r1);
Decryptage();
chatBox.Items.Add(r2);
}
private void button1_Click(object sender, EventArgs e)
{
Cryptage(messageBox.Text);
}
private void Decryptage()
{
// variables
string[] Tab_strDecryptage = Array.Empty<string>();
string strMessgeDecrypt = string.Empty;
byte[] Tab_byteDecompress = Array.Empty<byte>();
string strMessageDecompress;
// permet de lire les 10 derniers messages et les mets dans un string de byteNbrMsg
List<string> strText = File.ReadLines(strPath).Reverse().Take(byteNbrMsg).ToList();
// decrypte les messages
using (StreamReader sr = new StreamReader(strPath))
{
// boucle for qui decrypte les x derniers messages
for (int i = 0; i < byteNbrMsg; i++)
{
// split le string actuel en l'inversant ( vu que on inverse la lecture des string dans le string )
//Tab_strDecryptage = strText[i].Split('\').ToArray();
strMessageDecompress = strText[i];
Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);
Unzip(Tab_byteDecompress);
// boucle foreach qui permet de decrypter chaque entrée du tableau
foreach (string item in Tab_strDecryptage)
{
try
{
// ajoute au string chaque caractère decrypté lu de la ligne
strMessgeDecrypt += ((char)(Math.Sqrt(Convert.ToUInt64(item)) / shrtNbrRandom));
}
catch (Exception)
{
}
}
// ecrit le string
chatBox.Items.Add(strMessgeDecrypt);
// vide le string
strMessgeDecrypt = "";
}
}
// 45 ms pour completer
}
private void Cryptage(string strUser)
{
// variables
byte[] byteASCII;
string strCryptage = string.Empty;
string strETML = Path.GetFileName(Environment.GetEnvironmentVariable("USERPROFILE"));
byte[] Tab_byteCompress = new byte[1];
string strCompress;
// ecrit les caractère en ASCII
byteASCII = Encoding.ASCII.GetBytes(strETML + " : " + strUser);
// crypte les messages
foreach (byte item in byteASCII)
{
// ecrit dans le string chaque caractères crypté séparé par un " \ "
strCryptage += ((ulong)(Math.Pow(item * shrtNbrRandom, 2)) + "\");
}
// permet de compresser le string crypté
strCompress = Encoding.ASCII.GetString(Zip(strCryptage));
// ecrit le string dans le document texte
using (StreamWriter write = new StreamWriter(strPath, true))
{
write.WriteLine(strCompress);
}
}
private void messageBox_TextChanged(object sender, EventArgs e)
{
if (messageBox.Text != "")
{
sendButton.Visible = true;
}
else
{
sendButton.Visible = false;
}
}
public void CopyTo(Stream src, Stream dest)
{
byte[] bytes = new byte[4096];
int cnt;
// erreur: System.IO.InvalidDataException : 'Le nombre magique dans l'en-tête GZip n'est pas correct. Assurez-vous que votre passage s'opère dans un flux GZip.'
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
{
dest.Write(bytes, 0, cnt);
}
}
public 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 string Unzip(byte[] bytes)
{
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream())
// mso n'a aucune valeur en input
// le but est de copier GS qui a des valeurs a MSO
{
using (var gs = new GZipStream(msi, CompressionMode.Decompress))
{
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
}
}
目前,您正在使用 ASCII.GetString()
将加密的字节 [] 写入文件,并使用 ASCII.GetBytes()
从文件中读取。问题出现在这里;您写入文件的 byte[] 值与从文件中读取并转换为 byte[] 后获得的值不同。
如果您使用 Base64String 而不是 ASCII,它应该可以工作。您需要更改两行(我注释掉了这些行并在下面添加了新版本):
方法中解密:
//Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);
Tab_byteDecompress = Convert.FromBase64String(strMessageDecompress);
方法中Cryptage:
//strCompress = Encoding.ASCII.GetString(Zip(strCryptage));
strCompress = Convert.ToBase64String(Zip(strCryptage));
我是一名计算机学徒,3 个月前我们开始学习 C#。我只是请你帮忙,因为我必须执行一个 "Whatsapp" 类型的项目。目标是加密和压缩消息。我可以加密消息并压缩它,但我不能解压缩它。我有一个 "System.IO.InvalidDataException: 'The magic number in the GZip header is not correct. Make sure that your passage takes place in a GZip stream" 类型的错误。我将代码复制到另一个主题并尝试将其适配到我的程序中,但无济于事。感谢您的理解。
我的项目是用 Windows 表格制作的。评论是法语的(因为我是法国人,我的老师要求法语评论)但我认为我的代码很容易理解。
编辑:问题出现在我的方法 "Decompression" 第 139 行
post 我说的是: Compression/Decompression string with C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;
namespace ChatApp
{
public partial class Form1 : Form
{
private static string strPath = @"..\..\..\messages\communication.txt";
const byte byteNbrMsg = 2;
private static short shrtNbrRandom = 947;
public Form1()
{
InitializeComponent();
byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
string r2 = Unzip(r1);
Decryptage();
chatBox.Items.Add(r2);
}
private void button1_Click(object sender, EventArgs e)
{
Cryptage(messageBox.Text);
}
private void Decryptage()
{
// variables
string[] Tab_strDecryptage = Array.Empty<string>();
string strMessgeDecrypt = string.Empty;
byte[] Tab_byteDecompress = Array.Empty<byte>();
string strMessageDecompress;
// permet de lire les 10 derniers messages et les mets dans un string de byteNbrMsg
List<string> strText = File.ReadLines(strPath).Reverse().Take(byteNbrMsg).ToList();
// decrypte les messages
using (StreamReader sr = new StreamReader(strPath))
{
// boucle for qui decrypte les x derniers messages
for (int i = 0; i < byteNbrMsg; i++)
{
// split le string actuel en l'inversant ( vu que on inverse la lecture des string dans le string )
//Tab_strDecryptage = strText[i].Split('\').ToArray();
strMessageDecompress = strText[i];
Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);
Unzip(Tab_byteDecompress);
// boucle foreach qui permet de decrypter chaque entrée du tableau
foreach (string item in Tab_strDecryptage)
{
try
{
// ajoute au string chaque caractère decrypté lu de la ligne
strMessgeDecrypt += ((char)(Math.Sqrt(Convert.ToUInt64(item)) / shrtNbrRandom));
}
catch (Exception)
{
}
}
// ecrit le string
chatBox.Items.Add(strMessgeDecrypt);
// vide le string
strMessgeDecrypt = "";
}
}
// 45 ms pour completer
}
private void Cryptage(string strUser)
{
// variables
byte[] byteASCII;
string strCryptage = string.Empty;
string strETML = Path.GetFileName(Environment.GetEnvironmentVariable("USERPROFILE"));
byte[] Tab_byteCompress = new byte[1];
string strCompress;
// ecrit les caractère en ASCII
byteASCII = Encoding.ASCII.GetBytes(strETML + " : " + strUser);
// crypte les messages
foreach (byte item in byteASCII)
{
// ecrit dans le string chaque caractères crypté séparé par un " \ "
strCryptage += ((ulong)(Math.Pow(item * shrtNbrRandom, 2)) + "\");
}
// permet de compresser le string crypté
strCompress = Encoding.ASCII.GetString(Zip(strCryptage));
// ecrit le string dans le document texte
using (StreamWriter write = new StreamWriter(strPath, true))
{
write.WriteLine(strCompress);
}
}
private void messageBox_TextChanged(object sender, EventArgs e)
{
if (messageBox.Text != "")
{
sendButton.Visible = true;
}
else
{
sendButton.Visible = false;
}
}
public void CopyTo(Stream src, Stream dest)
{
byte[] bytes = new byte[4096];
int cnt;
// erreur: System.IO.InvalidDataException : 'Le nombre magique dans l'en-tête GZip n'est pas correct. Assurez-vous que votre passage s'opère dans un flux GZip.'
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
{
dest.Write(bytes, 0, cnt);
}
}
public 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 string Unzip(byte[] bytes)
{
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream())
// mso n'a aucune valeur en input
// le but est de copier GS qui a des valeurs a MSO
{
using (var gs = new GZipStream(msi, CompressionMode.Decompress))
{
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
}
}
目前,您正在使用 ASCII.GetString()
将加密的字节 [] 写入文件,并使用 ASCII.GetBytes()
从文件中读取。问题出现在这里;您写入文件的 byte[] 值与从文件中读取并转换为 byte[] 后获得的值不同。
如果您使用 Base64String 而不是 ASCII,它应该可以工作。您需要更改两行(我注释掉了这些行并在下面添加了新版本):
方法中解密:
//Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);
Tab_byteDecompress = Convert.FromBase64String(strMessageDecompress);
方法中Cryptage:
//strCompress = Encoding.ASCII.GetString(Zip(strCryptage));
strCompress = Convert.ToBase64String(Zip(strCryptage));