压缩:将指定的原字符串用 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; } }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于