/// <summary> /// 获取指定组合数量中最有价值的组合 /// </summary> /// <param name="bytes">查询数据</param> /// <param name="groupSize">组合大小</param> /// <returns>最有价值的组合</returns> public static CompressItem GetCompressItem(byte[] bytes, int groupSize) { var endIndex = bytes.Length - groupSize; //得到结束位索引 var compressItemDic = new Dictionary <CompressItem, int>(); //判断是否存在 for (int i = 0; i <= endIndex; i++) { var group = ByteGroup.Create(bytes, i, groupSize); //得到Group var item = new CompressItem { Group = group, Bytes = bytes, StartIndex = i }; if (compressItemDic.ContainsKey(item)) { compressItemDic[item]++; } else { compressItemDic[item] = 1; } } var items = compressItemDic.OrderByDescending(b => b.Value).ThenByDescending(b => b.Key.StartIndex) .ToArray(); //得到理论上最多组合数排序的结果 var maxItem = items.First().Key; //得到第一个理论上最多组合结果 maxItem.Count = GetCompressGroup(bytes, maxItem.Group, maxItem.StartIndex); //得到理论上第一个的实际可用组合数 for (var i = 1; i < items.Length; i++) { var item = items[i]; if (item.Value <= maxItem.Count) { break; //如果理论组合数还小于等于目前最多的实际组合数就没有必要继续搜索下去了 } item.Key.Count = GetCompressGroup(bytes, item.Key.Group, item.Key.StartIndex); //得到实际组合数量 //判断是否实际组合数量大于现在最多的 if (item.Key.Count > maxItem.Count) { maxItem = item.Key;//赋值目前为最多实际组合结果 } } return(maxItem); }
/// <summary> /// 压缩方法 /// </summary> /// <param name="source">压缩数据</param> /// <param name="item">进行压缩的组合</param> /// <returns>压缩后的结果</returns> public static byte[] Compress(byte[] source, CompressItem item) { var headerLength = 1 //版本号 + 1 //字典长度字段 + item.Group.Bytes.Length //字典内容字段 + 4; //总元素长度【有效位】 var group = item.Group; var compressByteCount = source.Length - (item.Count * group.Bytes.Length); var sumBit = (compressByteCount * 9) + (item.Count); var bytes = new byte[headerLength + (((sumBit - 1) / 8) + 1)]; bytes[0] = 0; //版本号为0 bytes[1] = (byte)group.Bytes.Length; //字典长度 Array.Copy(group.Bytes, 0, bytes, 2, group.Bytes.Length); //字典内容字段 Array.Copy(BitConverter.GetBytes(source.Length), 0, bytes, group.Bytes.Length + 1 + 1, 4); //总元素长度【有效位】 //循环压缩内容 var index = headerLength; //索引存入数据索引位置 var bitIndex = 0; //Bit索引位置 var groupSize = group.Bytes.Length; for (int i = 0; i < source.Length;) { //判断是否可以压缩组合 if (group.EqArray(source, i)) { AddBit(bytes, ref index, ref bitIndex, true); i += groupSize; } else { AddBit(bytes, ref index, ref bitIndex, false); AddByte(bytes, ref index, bitIndex, source[i]); i++; } } if (bitIndex != 0) { bytes[index] <<= (8 - bitIndex); //将最后一位位置挪到最高位,方便解压 } return(bytes); }