差异行压缩算法(C#实现)
private byte[] DifferenceRowOrder(int offset, int count, byte[] inbyte)//差异行命令(此处的offset和count都从1开始)
{
List<byte> result = new List<byte>();
if (offset >= 1 && offset <= 31 && count >= 1 && count <= 8)
{
offset -= 1;
count -= 1;
string order =Convert.ToString(count,2).PadLeft(3, '0') + Convert.ToString(offset,2).PadLeft(5, '0');
result.Add(Convert.ToByte(Convert.ToInt32(order, 2)));
result.AddRange(inbyte);
return result.ToArray();
}
else //大于31个字节
{
offset -= 31;
count -= 1;
string order =Convert.ToString(count,2).PadLeft(3, '0') + "11111";
result.Add(Convert.ToByte(Convert.ToInt32(order, 2)));
for (int i = 0; i < offset / 255; i++)
{
result.Add(Convert.ToByte(Convert.ToInt32("11111111", 2)));
}
offset = offset % 255;
if (offset != 0)
{
result.Add(Convert.ToByte(offset));
}
result.AddRange(inbyte);
return result.ToArray();
}
}
private List<string> DuplicateTopLine(List<byte> last, List<byte> currt)
{
List<int> indexs = new List<int>();
List<string> continuous = new List<string>();
if (last.Count != currt.Count)
{
if (last.Count < currt.Count)
{
int count = currt.Count - last.Count;
for (int i = 0; i < count; i++)
{
last.Add(0x00);
}
}
else
{
int count = last.Count - currt.Count;
for (int i = 0; i < count; i++)
{
currt.Add(0x00);
}
}
}
for (int i = 0; i < currt.Count; i++)
{
if (last[i] != currt[i])
{
if (indexs.Count>0&&indexs[indexs.Count - 1] == i - 1) //存在连续不同的索引
{
if (continuous[continuous.Count - 1].Contains("-"))
{
string []indexstring = continuous[continuous.Count - 1].Split('-');
continuous[continuous.Count - 1] = indexstring[0] + "-" + i;
}
else//上一个是单独的索引
{
continuous[continuous.Count - 1] = continuous[continuous.Count - 1] + "-" + i;
}
}
else
{
continuous.Add(i.ToString());
}
indexs.Add(i);
}
else
{
}
}
return continuous;
}
怎么调用
//下方的line为个数为8的倍数的二进制字符串,如果不为8的倍数,请使用PadRight用0补足
//输出结果为lineorder,lineorder由命令字节+替换字节+命令字节+替换字节......组成
List<byte> lineorder = new List<byte>();
templineBytes.Clear();
for (int k = 0; k < line.Length / 8; k++)
{
templineBytes.Add(Convert.ToByte(Convert.ToInt32(line.Substring(k * 8, 8), 2)));
}
List<string> continuousIndexs= DuplicateTopLine(lasttemplineBytes, templineBytes);
int lastindex=0;//上一个字节操作位
bool isin = false;
for (int m = 0; m < continuousIndexs.Count; m++)
{
if (continuousIndexs[m].Contains("-"))//是连续的不同索引块
{
string[] num = continuousIndexs[m].Split('-');
List<byte> currt = new List<byte>();
if (Convert.ToInt32(num[1]) >= templineBytes.Count)
{
if (Convert.ToInt32(num[0]) >= templineBytes.Count)
{
for (int k=0; k< Convert.ToInt32(num[1])- Convert.ToInt32(num[0]);k++)
{
currt.Add(0x00);
}
}
else
{
currt = templineBytes.GetRange(Convert.ToInt32(num[0]), Convert.ToInt32(templineBytes.Count-1) - Convert.ToInt32(num[0])+1);
}
}
else
{
currt = templineBytes.GetRange(Convert.ToInt32(num[0]), Convert.ToInt32(num[1]) - Convert.ToInt32(num[0])+1);
}
int startIndex = Convert.ToInt32(num[0]);//开始的数组索引
int endIndex = Convert.ToInt32(num[1]);//结束的数组索引
if (currt.Count > 8)
{
//大于8个字节再分
int forcount = currt.Count / 8;
int lastfor = currt.Count % 8;
for (int k=0;k< forcount;k++)
{
//0-7
if (!isin)
{
if (k == 0)
{
lineorder.AddRange(DifferenceRowOrder(startIndex - lastindex + 1, 8, currt.GetRange(k * 8, 8).ToArray()));//使用相对偏移量
}
else
{
lineorder.AddRange(DifferenceRowOrder(1, 8, currt.GetRange(k * 8, 8).ToArray()));//使用相对偏移量
}
isin = true;
}
else
{
if (k == 0)
{
lineorder.AddRange(DifferenceRowOrder(startIndex - lastindex, 8, currt.GetRange(k * 8, 8).ToArray()));//使用相对偏移量
}
else
{
lineorder.AddRange(DifferenceRowOrder(1, 8, currt.GetRange(k * 8, 8).ToArray()));//使用相对偏移量
}
}
}
if (lastfor > 0)
{
lineorder.AddRange(DifferenceRowOrder(1, lastfor, currt.GetRange(forcount * 8, lastfor).ToArray()));//使用相对偏移量
}
lastindex = endIndex;
}
else
{
//当前连续小于8字节
if (!isin)
{
lineorder.AddRange(DifferenceRowOrder(startIndex - lastindex + 1, currt.Count, currt.ToArray()));//使用相对偏移量
isin = true;
}
else
{
lineorder.AddRange(DifferenceRowOrder(startIndex - lastindex, currt.Count, currt.ToArray()));//使用相对偏移量
}
lastindex = endIndex;
}
}
else //是单个的不同索引
{
int currtindex = Convert.ToInt32(continuousIndexs[m]);
if (currtindex >= templineBytes.Count)
{
if (currtindex - lastindex + 1 <= 0)
{
throw new Exception();
}
if (!isin)
{
lineorder.AddRange(DifferenceRowOrder(currtindex - lastindex + 1, 1, new byte[] { 0x00}));//使用相对偏移量
isin = true;
}
else
{
lineorder.AddRange(DifferenceRowOrder(currtindex - lastindex, 1, new byte[] { 0x00 }));//使用相对偏移量
}
}
else
{
if (currtindex - lastindex + 1 <= 0)
{
throw new Exception();
}
if (!isin)
{
lineorder.AddRange(DifferenceRowOrder(currtindex - lastindex + 1, 1, new byte[] { templineBytes[currtindex] }));//使用相对偏移量
isin = true;
}
else
{
lineorder.AddRange(DifferenceRowOrder(currtindex - lastindex, 1, new byte[] { templineBytes[currtindex] }));//使用相对偏移量
}
}
lastindex = currtindex;
}
}
lasttemplineBytes = templineBytes;
if (lineorder.Count != 0)
{
result.AddRange(Encoding.ASCII.GetBytes((lineorder.Count) + ""));//个数
result.Add(0x57);//W
result.AddRange(lineorder);
}
else
{
result.Add(0x1B);//ESC
result.Add(0x2A);//*
result.Add(0x62);//b
result.Add(0x31);//1
result.Add(0x59);//Y
}
差异行压缩算法(C#实现)的更多相关文章
- [原创]首次制作JQueryUI插件-Timeline时间轴
特点: 1. 支持多左右滚动,左右拖动. 2. 时间轴可上下两种显示方式. 3. 支持两种模式的平滑滚动/拖动. 4. 行压缩(后续版本此处可设置是否开启,上传的代码不带这个功能). 5. 支持hov ...
- Beyond Compare 2
Beyond Compare 2 确实很好用,差异行不交叉,自动留出空白,比windiff要清楚.
- 如何为Linux生成和打上patch
通过diff工具生成补丁, patch工具打上补丁. 在使用diff之前, 你需要保留一份未修改过的源码, 然后在其它地方修改源码的一份拷贝. diff对比这两份源码生成patch. 修改过的源码必须 ...
- Linux下生成patch和打patch
转自:http://blog.csdn.net/dl0914791011/article/details/17299103 通过diff工具生成补丁, patch工具打上补丁. 在使用diff之前, ...
- Vim文本编辑器 指令簿(二)
常常处理文本以及常常须要写代码的人,都会有自己比較常常使用的编辑器,本人喜欢用Vim.理由就是Vim编辑器灵活,而且能够达到纯键盘操作,使用纯熟情况下,根本不须要鼠标操作.听起来是不是非常酷的?只是别 ...
- 17 个 Linux 下用于 C/C++ 的最好的 IDE
C++,一个众所周知的 C 语言的扩展,是一个优秀的.强大的.通用编程语言,它能够提供现代化的.通用的编程功能,可以用于开发包括视频游戏.搜索引擎.其他计算机软件乃至操作系统等在内的各种大型应用. C ...
- MySQL--如何快速对比数据
在MySQL运维中,研发同事想对比下两个不同实例上的数据并找出差异,除主键外还需要对比每一个字段,如何做呢? 第一种方案,写程序将两个实例上的每一行数据取出来进行对比,理论可行,但是对比时间较长. 第 ...
- Python实现C代码统计工具(三)
目录 Python实现C代码统计工具(三) 声明 一. 性能分析 1.1 分析单条语句 1.2 分析代码片段 1.3 分析整个模块 二. 制作exe Python实现C代码统计工具(三) 标签: Py ...
- linux打patch简单示例
在项目中,有些模块是开源的,没有源码或者不能改动源码,想要修复.优化里面的Bug,这时就需要用到patch了. 1. 生成patch 制作补丁有两种法法,diff和quilt. 1.1 di ...
- MySQL —— 如何快速对比数据?
我们在MySql中想要对比下两个不同的实例上的数据并且找出差异,除了主键之外我们还要对比每一个字段,应该怎么做呢? 方案一:写一个程序将两个实例里面的每一行数据都分别取出来对比,但是耗时我们无法估计, ...
随机推荐
- 使用LabVIEW实现 DeepLabv3+ 语义分割含源码
前言 图像分割可以分为两类:语义分割(Semantic Segmentation)和实例分割(Instance Segmentation),前面已经给大家介绍过两者的区别,并就如何在labview上实 ...
- Python数据分析易错知识点归纳(四):Matplotlib
四.matplotlib 基本特性 import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 50) y1 = ...
- 2021-8-2 Mysql个人练习题
创建学生表 CREATE TABLE student( id int, uname VARCHAR(20), chinese FLOAT, english FLOAT, math FLOAT ); I ...
- jQuery事件冒泡和默行为
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [Python]树基础
关于树 树是一种数据结构,由n个有限节点组成的一个具有层次关系的集合.二叉树则是每个节点最多有两个子树的树结构.二叉树一般有以下性质: 二叉树第k层上的节点数目最多为 \(2^{k-1}\) 深度为 ...
- nginx配置源IP访问控制
通过nginx的ngx_http_access_module模块,可实现对客户端的源IP地址进行允许或拒绝访问控制.该模块默认已编译. 允许访问指令 名称 允许访问指令 指令 allow 作用域 ht ...
- centos7升级内核到最新稳定版
前言 centos7默认的内核版本才3.10,诸如VXLAN.eBPF等特性无法体验,因此需要升级.目前(2022.02)Linux的内核版本已更新到5.16. 步骤 更新仓库 yum update ...
- 使用 Vue 实现页面访问拦截
目录 1 Vue 路由与导航守卫 1.1 Vue 路由简介 1.2 导航守卫概述 2 实现访问拦截的核心概念 2.1 路由守卫介绍 2.1.1 前置守卫(beforeEach) 2.1.2 后置钩子( ...
- 基于CUBEMX的STM32F4 Hal库,配置LVGL(无操作系统版)
本篇文章移植思路适用于所有嵌入式MCU,包括Arm,STM32,NXP,乐鑫,Nuvoton,Arduino,RT-Thread,Zephyr,NuttX,Adafruit等等. 为什么要写这一篇移植 ...
- 3.你不知道的go语言控制语句
目录 本篇前瞻 Leetcode习题9 题目描述 题目分析 代码编写 知识点归纳 控制结构 顺序结构(Sequence) 声明和赋值 算术运算符 位运算符 逻辑运算 分支结构 if 语句 switch ...