.net 如何将字节数组的已编码字符串表示形式转换为实际的字节数组?C#

c0vxltue  于 2022-11-19  发布在  .NET
关注(0)|答案(1)|浏览(217)

问题在于:我们有一个系统,事件和预测有一个列有效负载,它是一个序列化的对象。这个有效负载是一个字符串,但出于性能和节省磁盘空间的考虑,我们开始在数据库中保存字符串的压缩版本。每当从数据库中提取时,我们都会解压缩它。
压缩和解压缩代码

using System.IO;
using System.IO.Compression;
using System.Text;

namespace DemoEFCore.Helpers
{
    public class CompressionHelper
    {
        public static byte[] Compress(string stringData)
        {
            var stringBytes = Encoding.UTF8.GetBytes(stringData);
            
            using var output = new MemoryStream();
            using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Fastest))
            {
                dstream.Write(stringBytes, 0, stringBytes.Length);
            }
            return output.ToArray();
        }

        public static string Decompress(byte[] data)
        {
            using var input = new MemoryStream(data);
            using var output = new MemoryStream();
            using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
            {
                dstream.CopyTo(output);
            }
            var bytes = output.ToArray();
            return Encoding.UTF8.GetString(bytes);
        }

    }
}

它工作得非常好,而且确实提高了性能。
但有时当你修复一个bug时,你会直接进入数据库查看一个具体记录的有效负载。我以前可以复制它并粘贴到一些JSON美化器中,但现在我只能复制编码的表示。
screenshot from db

0x8590416BC3300C85FFCA7867BBC88E9DC4BE6D1D8C5DB6427BEAD82189952D236D83E3144AE97F1F69BBF3408787D07B9FA4335E033C7496DBB6B546EADCE6D2144ECBD29293A1A6D0385B84820C049691ABC4E131CD16D25A2A25C96CA8F4B6F4E4163A3345A1DD1602AB7808539336A781E1151109ACA781E33AC56EFF058FA7581D1902EFF50F376984FFC010BB2327082D529C5840B9822429496A43E4AFB58538E3ADDA31FC2DEF65D633AE6B18DEDA8515584D75DF8DDF1C6FB73559C921AFA42D9D9626574A56D690AC759B99AC0A2E84664EF833C19FB13CEC866A7FBA83C679F187E6D683C0CC1CE1F753DF8BEBFFEE6A5C1FDAF4CC3D270EF06DD58F7CF977E0F3F20B

我们要做的是复制这个字符串,粘贴到我们的应用程序中,并获得解码的JSON字符串。这听起来很容易,因为我们已经有了CompressionHelper.Decompress方法,但它接受一个字节数组作为参数。我找到了3个解决方案,如何将这样的字符串转换为字节数组,但他们不为我工作。
1.

var s = "0xB5945F6FDA3014C5BF0ABACF71E5FF2179AB18D22A552D5A190FDBFAE0C437C11A719013B67515DF7D22A40C06A3ADB63EC6F139E7FADE9FFD08571652A054B0445B4164CE389179C249A6D112ADA842458B38CB044470632A84142675684766B1B8A92BE74DEB6A3F416F9D2FAF5DD3CE1C7E8768B7E735F6336C1A5CF421D339D6B60E8371D364184A0CBD69FFFBAAAA9C2FE7A6EA97BB9CD84A9E6405126D634EE490496292212536CF448C4C67B99610C1A8AE2A0CB9338BDB501AEF7E7667E81C146A9170A949A20D25D2E69464C6E4C42844AE5070610A88608AF9DCBBFC8481502C16BC50246668881446902CE78288213342E499A6F1102298D50FA6C49B559561801418D707755D96E8DBA3E2B2586A5B5843322C349142539220CB89B454243197892AD4799BBE7923D32C310CEEE66EB974BE1C5CB7F60222B8FDEE31FC53F46987F3A9D38725422A28A511DCB5A65D3590F2EE6BEA2ABC2D7ACA36E071CA19619C303165C394A994F10BC919535A7FDA70109CCFDDF2702A903E3E713BFEB2A294EBBBC1D4F8AF181A88B6F4BF68E8EB7D6EDEA1B10BE7B181F4F3234C4C681F2065DBA2BBE3B058D1083E6081017D8E93DAF91652A936877C5FAF4203A9B8A0741D9D5677FB8ED49D7FAF5654FE5DCF9FD7F33372D9059D8D1F9E093FA94EF68B3F17BE05E128FCA59D7B3E5C76B5DFF7B89F9C648FDF1E98AFA9675FBD65E24FF54133B6F5FC06E140FEFC208F4038D0BF10C3FBBDCBF3D491F10FD7B490B66185118CBFA16FB7B45F9665C0D2B4F89AA7FD638361B3DFAF168B087616330C8DAB3DA4DD4DD82DFF4F67B6B9636FE32CE337F41EAEEF23D8F5474670D58CE6C69768B73359FF02";
            
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
var s1 = CompressionHelper.Decompress(stream.ToArray());

var s1 = CompressionHeplepr.Decompress(stream.ToArray());抛出异常System.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method.
2.

var s = "0xB5945F6FDA3014C5BF0ABACF71E5FF2179AB18D22A552D5A190FDBFAE0C437C11A719013B67515DF7D22A40C06A3ADB63EC6F139E7FADE9FFD08571652A054B0445B4164CE389179C249A6D112ADA842458B38CB044470632A84142675684766B1B8A92BE74DEB6A3F416F9D2FAF5DD3CE1C7E8768B7E735F6336C1A5CF421D339D6B60E8371D364184A0CBD69FFFBAAAA9C2FE7A6EA97BB9CD84A9E6405126D634EE490496292212536CF448C4C67B99610C1A8AE2A0CB9338BDB501AEF7E7667E81C146A9170A949A20D25D2E69464C6E4C42844AE5070610A88608AF9DCBBFC8481502C16BC50246668881446902CE78288213342E499A6F1102298D50FA6C49B559561801418D707755D96E8DBA3E2B2586A5B5843322C349142539220CB89B454243197892AD4799BBE7923D32C310CEEE66EB974BE1C5CB7F60222B8FDEE31FC53F46987F3A9D38725422A28A511DCB5A65D3590F2EE6BEA2ABC2D7ACA36E071CA19619C303165C394A994F10BC919535A7FDA70109CCFDDF2702A903E3E713BFEB2A294EBBBC1D4F8AF181A88B6F4BF68E8EB7D6EDEA1B10BE7B181F4F3234C4C681F2065DBA2BBE3B058D1083E6081017D8E93DAF91652A936877C5FAF4203A9B8A0741D9D5677FB8ED49D7FAF5654FE5DCF9FD7F33372D9059D8D1F9E093FA94EF68B3F17BE05E128FCA59D7B3E5C76B5DFF7B89F9C648FDF1E98AFA9675FBD65E24FF54133B6F5FC06E140FEFC208F4038D0BF10C3FBBDCBF3D491F10FD7B490B66185118CBFA16FB7B45F9665C0D2B4F89AA7FD638361B3DFAF168B087616330C8DAB3DA4DD4DD82DFF4F67B6B9636FE32CE337F41EAEEF23D8F5474670D58CE6C69768B73359FF02";
        
        var b = Convert.FromBase64String(s);
        var jsonString = CompressionHelper.Decompress(b);

var b = Convert.FromBase64String(s);抛出此异常System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
3.

try
        {
            var s = "0xB5945F6FDA3014C5BF0ABACF71E5FF2179AB18D22A552D5A190FDBFAE0C437C11A719013B67515DF7D22A40C06A3ADB63EC6F139E7FADE9FFD08571652A054B0445B4164CE389179C249A6D112ADA842458B38CB044470632A84142675684766B1B8A92BE74DEB6A3F416F9D2FAF5DD3CE1C7E8768B7E735F6336C1A5CF421D339D6B60E8371D364184A0CBD69FFFBAAAA9C2FE7A6EA97BB9CD84A9E6405126D634EE490496292212536CF448C4C67B99610C1A8AE2A0CB9338BDB501AEF7E7667E81C146A9170A949A20D25D2E69464C6E4C42844AE5070610A88608AF9DCBBFC8481502C16BC50246668881446902CE78288213342E499A6F1102298D50FA6C49B559561801418D707755D96E8DBA3E2B2586A5B5843322C349142539220CB89B454243197892AD4799BBE7923D32C310CEEE66EB974BE1C5CB7F60222B8FDEE31FC53F46987F3A9D38725422A28A511DCB5A65D3590F2EE6BEA2ABC2D7ACA36E071CA19619C303165C394A994F10BC919535A7FDA70109CCFDDF2702A903E3E713BFEB2A294EBBBC1D4F8AF181A88B6F4BF68E8EB7D6EDEA1B10BE7B181F4F3234C4C681F2065DBA2BBE3B058D1083E6081017D8E93DAF91652A936877C5FAF4203A9B8A0741D9D5677FB8ED49D7FAF5654FE5DCF9FD7F33372D9059D8D1F9E093FA94EF68B3F17BE05E128FCA59D7B3E5C76B5DFF7B89F9C648FDF1E98AFA9675FBD65E24FF54133B6F5FC06E140FEFC208F4038D0BF10C3FBBDCBF3D491F10FD7B490B66185118CBFA16FB7B45F9665C0D2B4F89AA7FD638361B3DFAF168B087616330C8DAB3DA4DD4DD82DFF4F67B6B9636FE32CE337F41EAEEF23D8F5474670D58CE6C69768B73359FF02";
            //var substring = s.Substring(2);
        
            var byteArray = new byte[s.Length];
            for (var i = 0; i < s.Length; i++)
            {
                var b = Byte.Parse(s[i].ToString());
                byteArray[i] = b;
            }
        
            var jsonString = CompressionHelper.Decompress(byteArray);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }

引发此异常

System.FormatException: Input string was not in a correct format.
   at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
   at System.Byte.Parse(String s)

你能帮我想办法解决我的问题吗?

siotufzp

siotufzp1#

@madmonk46非常感谢。Convert.FromHexString真的帮了大忙。一开始我找不到这个方法,因为我的演示项目是在.NET Core 3.1上,但从.NET 5开始支持Convert.FromHexString。幸运的是,我们的项目是在.NET 5上,现在我们正在迁移到. NET 6))
此外,它不适用于从0x开始字符串

var stringFromDataBase = "0x8590416BC3300C85FFCA7867BBC88E9DC4BE6D1D8C5DB6427BEAD82189952D236D83E3144AE97F1F69BBF3408787D07B9FA4335E033C7496DBB6B546EADCE6D2144ECBD29293A1A6D0385B84820C049691ABC4E131CD16D25A2A25C96CA8F4B6F4E4163A3345A1DD1602AB7808539336A781E1151109ACA781E33AC56EFF058FA7581D1902EFF50F376984FFC010BB2327082D529C5840B9822429496A43E4AFB58538E3ADDA31FC2DEF65D633AE6B18DEDA8515584D75DF8DDF1C6FB73559C921AFA42D9D9626574A56D690AC759B99AC0A2E84664EF833C19FB13CEC866A7FBA83C679F187E6D683C0CC1CE1F753DF8BEBFFEE6A5C1FDAF4CC3D270EF06DD58F7CF977E0F3F20B";
var bytesArray = Convert.FromHexString(stringFromDataBase);
var jsonString = CompressionHelper.Decompress(bytesArray);

此代码将引发

System.FormatException: The input is not a valid hex string as it contains a non-hex character.

因此需要添加一行代码。

var stringFromDataBase = "0x8590416BC3300C85FFCA7867BBC88E9DC4BE6D1D8C5DB6427BEAD82189952D236D83E3144AE97F1F69BBF3408787D07B9FA4335E033C7496DBB6B546EADCE6D2144ECBD29293A1A6D0385B84820C049691ABC4E131CD16D25A2A25C96CA8F4B6F4E4163A3345A1DD1602AB7808539336A781E1151109ACA781E33AC56EFF058FA7581D1902EFF50F376984FFC010BB2327082D529C5840B9822429496A43E4AFB58538E3ADDA31FC2DEF65D633AE6B18DEDA8515584D75DF8DDF1C6FB73559C921AFA42D9D9626574A56D690AC759B99AC0A2E84664EF833C19FB13CEC866A7FBA83C679F187E6D683C0CC1CE1F753DF8BEBFFEE6A5C1FDAF4CC3D270EF06DD58F7CF977E0F3F20B";
var substring = stringFromDataBase.Substring(2);
var bytesArray = Convert.FromHexString(substring);
var jsonString = CompressionHelper.Decompress(bytesArray);

再次感谢您的快速帮助,madmonk 46!

相关问题