C#ASCII-base85编码解码
public class ASCII85 { static List<byte> whiteSpaces = new List<byte>(new byte[] { 0, 9, 10, 12, 13, 32 }); public static byte[] Encode(byte[] bs) { using (MemoryStream source = new MemoryStream(bs)) { using (MemoryStream target = new MemoryStream()) { Encode(source, target); return target.ToArray(); } } } public static byte[] Decode(byte[] bs) { using (MemoryStream source = new MemoryStream(bs)) { using (MemoryStream target = new MemoryStream()) { Decode(source, target); return target.ToArray(); } } } public static byte[] Encode(string str) { byte[] bs = Encode(Encoding.UTF8.GetBytes(str)); return bs; } public static byte[] Decode(string str) { byte[] bs = Decode(Encoding.UTF8.GetBytes(str)); return bs; } public static void Decode(Stream encoded, Stream decoded) {
//过滤<~...~> bool trimStart = false, trimEnd = false; encoded.Position = 0; if (encoded.ReadByte() == (byte)'<' && encoded.ReadByte() == (byte)'~') trimStart = true; encoded.Position = encoded.Length - 2; if (encoded.ReadByte() == (byte)'~' && encoded.ReadByte() == (byte)'>') trimEnd = true; encoded.Position = trimStart ? 2 : 0; long length = trimEnd ? encoded.Length - 2 : encoded.Length; byte[] bs; uint[] bs1; int t, len; while (encoded.Position < length) { if (encoded.ReadByte() == 122) { decoded.Write(new byte[4], 0, 4); continue; } len = 0; bs1 = new uint[5]; encoded.Position--; for (int i = 0; i < 5; i++) { t = SkipIfWhiteSpace(encoded); if (t < 0) bs1[i] = 84; else { bs1[i] = (uint)t - 33; len++; } } uint value = bs1[0] * 85 * 85 * 85 * 85 + bs1[1] * 85 * 85 * 85 + bs1[2] * 85 * 85 + bs1[3] * 85 + bs1[4]; bs = BitConverter.GetBytes(value).Reverse().Take(len - 1).ToArray(); decoded.Write(bs, 0, bs.Count()); } } public static void Encode(Stream source, Stream target) { source.Position = 0; target.Position = 0; byte[] bs = new byte[5]; int len = 0, c1, c2, c3, c4; while (source.Position < source.Length) { c1 = source.ReadByte(); c2 = source.ReadByte(); c3 = source.ReadByte(); c4 = source.ReadByte(); len = 1; if (c2 > -1) len++; else c2 = 0; if (c3 > -1) len++; else c3 = 0; if (c4 > -1) len++; else c4 = 0; if ((c1 | c2 | c3 | c4) == 0) { target.WriteByte((byte)122); continue; } uint a = (uint)((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)); uint b; for (int i = 0; i < 5; i++) { b = a % 85; a = a / 85; bs[4 - i] = ((byte)(b + 33)); } for (int i = 0; i < len + 1; i++) target.WriteByte(bs[i]); } }
//跳过空白字节返回字节 static int SkipIfWhiteSpace(Stream encoded) { int r = 0; do { r = encoded.ReadByte(); } while (r > -1 && whiteSpaces.Contains((byte)r)); return r; } }
调用方式:
string str = "ABCDefg一二三四五[调皮]🐶"; string encode = ASCII85.Encode(str); //5sdq,AS,T9\:EYON9%L*jdVb#\s-F_Y_2,-Y$LOhOL> string decode = ASCII85.Decode(encode); //ABCDefg一二三四五[调皮]🐶