Java C# LZMA 字符串压缩解压

本贴最后更新于 3029 天前,其中的信息可能已经渤澥桑田

压缩:将指定的原字符串用 LZMA 算法压缩,然后以 BASE64 编码
解压:将指定的 BASE64 编码的字符串用 LZMA 解压,返回原字符串

原字符串为 UTF-8 编码。

Java 版本

导入包

基本都是 JDK 内置的包,BASE64 部分可能需要替换一下(JDK8 已经自带 BASE64)。

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils;

实现部分

/** * 使用 lzma 进行压缩. * * @param str 压缩前的文本 * @return 压缩后的文本(BASE64 编码) * @throws IOException 如果解压异常 */ public static String lzma(final String str) throws IOException { if (str == null || "".equals(str)) { return str; } final SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes()); try { encoder.SetEndMarkerMode(false); encoder.WriteCoderProperties(out); final long fileSize = in.available(); for (int i = 0; i < 8; i++) { out.write((int) (fileSize >>> (8 * i)) & 0xFF); } encoder.Code(in, out, -1, -1, null); final byte[] compressed = out.toByteArray(); return new String(Base64.encodeBase64(compressed), "UTF-8"); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); } } /** * 使用 lzma 进行解压缩. * * @param compressedStr 压缩后的文本(BASE64 编码) * @return 解压后的文本 * @throws IOException 如果解压异常 */ public static String unlzma(final String compressedStr) throws IOException { if (null == compressedStr || "".equals(compressedStr)) { return compressedStr; } final SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(compressedStr)); try { final int propertiesSize = 5; final byte[] properties = new byte[propertiesSize]; if (in.read(properties, 0, propertiesSize) != propertiesSize) { throw new IOException("input .lzma file is too short"); } if (!decoder.SetDecoderProperties(properties)) { throw new IOException("Incorrect stream properties"); } long outSize = 0; for (int i = 0; i < 8; i++) { final int v = in.read(); if (v < 0) { throw new IOException("Can't read stream size"); } outSize |= ((long) v) << (8 * i); } if (!decoder.Code(in, out, outSize)) { throw new IOException("Error in data stream"); } return out.toString("UTF-8"); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); } }

C# 版本

命名空间

using System; using System.Text; using System.IO; using SevenZip;

实现部分

/// <summary> /// 使用 lzma 进行压缩 /// </summary> /// <param name="str">压缩前的文本</param> /// <returns>压缩后的文本(BASE64 编码)</returns> public static string lzma(string str) { if (null == str || "".Equals(str)) { return str; } byte[] buffer = Encoding.UTF8.GetBytes(str); byte[] compressed = SevenZipHelper.Compress(buffer); return Convert.ToBase64String(compressed); } /// <summary> /// 使用 lzma 进行解压缩 /// </summary> /// <param name="compressedStr">压缩后的文本(BASE64 编码)</param> /// <returns>解压后的文本</returns> public static string unlzma(string compressedStr) { if (null == compressedStr || "".Equals(compressedStr)) { return compressedStr; } byte[] decompressed = SevenZipHelper.Decompress(Convert.FromBase64String(compressedStr)); return Encoding.UTF8.GetString(decompressed); } public static class SevenZipHelper { static int dictionary = 1 << 23; // static Int32 posStateBits = 2; // static Int32 litContextBits = 3; // for normal files // UInt32 litContextBits = 0; // for 32-bit data // static Int32 litPosBits = 0; // UInt32 litPosBits = 2; // for 32-bit data // static Int32 algorithm = 2; // static Int32 numFastBytes = 128; static bool eos = false; static CoderPropID[] propIDs = { CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits, CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker }; // these are the default properties, keeping it simple for now: static object[] properties = { (Int32)(dictionary), (Int32)(2), (Int32)(3), (Int32)(0), (Int32)(2), (Int32)(128), "bt4", eos }; public static byte[] Compress(byte[] inputBytes) { MemoryStream inStream = new MemoryStream(inputBytes); MemoryStream outStream = new MemoryStream(); SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); encoder.SetCoderProperties(propIDs, properties); encoder.WriteCoderProperties(outStream); long fileSize = inStream.Length; for (int i = 0; i < 8; i++) outStream.WriteByte((Byte)(fileSize >> (8 * i))); encoder.Code(inStream, outStream, -1, -1, null); return outStream.ToArray(); } public static byte[] Decompress(byte[] inputBytes) { MemoryStream newInStream = new MemoryStream(inputBytes); SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); newInStream.Seek(0, 0); MemoryStream newOutStream = new MemoryStream(); byte[] properties2 = new byte[5]; if (newInStream.Read(properties2, 0, 5) != 5) throw (new Exception("input .lzma is too short")); long outSize = 0; for (int i = 0; i < 8; i++) { int v = newInStream.ReadByte(); if (v < 0) throw (new Exception("Can't Read 1")); outSize |= ((long)(byte)v) << (8 * i); } decoder.SetDecoderProperties(properties2); long compressedSize = newInStream.Length - newInStream.Position; decoder.Code(newInStream, newOutStream, compressedSize, outSize, null); byte[] b = newOutStream.ToArray(); return b; } }

姊妹篇: https://hacpai.com/article/1480569906672

  • LZMA
    1 引用 • 6 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3195 引用 • 8215 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • ZephyrJung

    双修的感觉如何

    1 回复
  • 88250

    复制粘贴有点累

  • yangyujiao via macOS

    终于可以评论了
    你还会 C#呀。。。
    chrome 崩溃了 7 8 次····

    1 回复
  • 88250

    我就是网络搬运工 + 照猫画虎..

    1 回复
  • tomaer via Linux

    你总和 @yangyujiao 在论坛上这样搞,不怕 V 收拾你吗?

  • jonwinters via Ubuntu

    弄个 Javascript 版本就好了

请输入回帖内容 ...