33
44namespace Lagrange . Core . Utility . Compression ;
55
6- internal static class ZCompression
6+ public static class ZCompression
77{
88 public static byte [ ] ZCompress ( byte [ ] data , byte [ ] ? header = null )
99 {
@@ -15,34 +15,52 @@ public static byte[] ZCompress(byte[] data, byte[]? header = null)
1515 stream . WriteByte ( 0xDA ) ; // Zlib header
1616
1717 stream . Write ( deflate . AsSpan ( ) ) ;
18-
19- var checksum = Adler32 ( data ) ;
20- stream . Write ( checksum . AsSpan ( ) ) ;
21-
18+
19+ Span < byte > checksum = stackalloc byte [ 4 ] ;
20+ BinaryPrimitives . WriteUInt32BigEndian ( checksum , Adler32 ( data ) ) ;
21+ stream . Write ( checksum ) ;
22+
2223 return stream . ToArray ( ) ;
2324 }
24-
25+
2526 public static byte [ ] ZCompress ( string data , byte [ ] ? header = null ) => ZCompress ( Encoding . UTF8 . GetBytes ( data ) , header ) ;
2627
28+ public static byte [ ] ZCompress ( ReadOnlySpan < byte > data , ReadOnlySpan < byte > header = default )
29+ {
30+ using var stream = new MemoryStream ( ) ;
31+ var deflate = Common . Deflate ( data ) ;
32+
33+ stream . Write ( header ) ;
34+ stream . WriteByte ( 0x78 ) ; // Zlib header
35+ stream . WriteByte ( 0xDA ) ; // Zlib header
36+
37+ stream . Write ( deflate . AsSpan ( ) ) ;
38+
39+ Span < byte > checksum = stackalloc byte [ 4 ] ;
40+ BinaryPrimitives . WriteUInt32BigEndian ( checksum , Adler32 ( data ) ) ;
41+ stream . Write ( checksum ) ;
42+
43+ return stream . ToArray ( ) ;
44+ }
45+
2746 public static byte [ ] ZDecompress ( ReadOnlySpan < byte > data , bool validate = true )
2847 {
29- var checksum = data [ ^ 4 ..] ;
30-
48+ uint expectedChecksum = BinaryPrimitives . ReadUInt32BigEndian ( data [ ^ 4 ..] ) ;
49+
3150 var inflate = Common . Inflate ( data [ 2 ..^ 4 ] ) ;
32- if ( validate ) return checksum . SequenceEqual ( Adler32 ( inflate ) ) ? inflate : throw new Exception ( "Checksum mismatch" ) ;
51+ if ( validate && Adler32 ( inflate ) != expectedChecksum ) throw new Exception ( "Checksum mismatch" ) ;
52+
3353 return inflate ;
3454 }
35-
36- private static byte [ ] Adler32 ( byte [ ] data )
55+
56+ private static uint Adler32 ( ReadOnlySpan < byte > data )
3757 {
3858 uint a = 1 , b = 0 ;
3959 foreach ( byte t in data )
4060 {
4161 a = ( a + t ) % 65521 ;
4262 b = ( b + a ) % 65521 ;
4363 }
44- var result = new byte [ 4 ] ;
45- BinaryPrimitives . WriteUInt32BigEndian ( result , ( b << 16 ) | a ) ;
46- return result ;
64+ return ( b << 16 ) | a ;
4765 }
48- }
66+ }
0 commit comments