编码解码_解码器编码 - CSDN
  • 文章目录编码解码概念理解URI (Uniform Resource Identifier)构成相对URI与绝对URIURL (Uniform Resource Locator)1. URL构成2. URL缺点URN (Uniform Resource Name)URI URL URN联系区别常用...

    概念理解

    编码解码

    编码

    编码:把使用者能看懂的数据转化成程序可以读懂的数据;

    解码

    解码:把程序可以读懂的数据转换成使用者能看懂的数据;

    URI (Uniform Resource Identifier)

    1. A URI (Uniform Resource Identifier) is a string that refers to a resource.
    2. URI(统一资源标识符)是一个指向资源的字符串
    3. URI可视为URL或者URN或者两者兼有。
    1. URI构成

    按照 URI 标准,http://www.cisco.com/en/US/partners/index.html —— 实际上是一个 URI,并且它由以下三部分组成:

    1. 方案名 (http)
    2. 域名 (www.cisco.com)
    3. 路径 (/en/US/partners/index.html)
    2. URI示例
    ftp://ftp.is.co.za/rfc/rfc1808.txt
    http://www.ietf.org/rfc/rfc2396.txt
    ldap://[2001:db8::7]/c=GB?objectClass?one
    mailto:John.Doe@example.com
    news:comp.infosystems.www.servers.unix
    tel:+1-816-555-1212
    telnet://192.0.2.16:80/
    urn:oasis:names:specification:docbook:dtd:xml:4.1.2
    
    注意:www.yahoo.com/sports不是一个真正的URI,它只是对
    http://www.yahoo.com/sports 的一种简写,是一种受流行的
    web浏览器用户界面支持的格式;
    
    3. 相对URI与绝对URI

    绝对的URI指以scheme(后面跟着冒号)开头的URI。

    可以把绝对的URI看作是以某种方式引用某种资源,而这种方式对标识符出现的环境没有依赖。如果使用文件系统作类比,绝对的URI类似于从根目录开始的某个文件的径。

    http://域名
    mailto:xxx@xxx.xx
    news:地址
    xyz://whatever
    

    相对的URI不是以scheme(后面跟着冒号)开始的URI。

    可以把相对的URI看作是以某种方式引用某种资源,而这种方式依赖于标识符出现的环境。如果用文件系统作类比,相对的URI类似于从当前目录开始的文件路径。

    articles/articles.html
    ../icons/logo.gif
    ../文件D
    
    • URL (Uniform Resource Locator)

    1. Uniform Resource Locator (URL) is a text string specifying where a resource can be found on the Internet.
    2. URL 通常用来指定Web上资源文件的具体位置。
    3. In the context of HTTP,URLs are called “Web address” or “link”
    4. URLs can also be used for file transfer (FTP) , emails (SMTP), and other applications.
    1. URL构成

    URL格式由下列三部分组成:

    1. 协议/服务方式
    2. 主机IP地址(有时候也包括端口号)
    3. 主机资源的具体地址,如目录、文件名等
      第一部分和第二部分之间用“ : // ”隔开,第二部分和第三部分之间用“/”隔开。第一部分和第二部分不可缺少,第三部分可以省略。
    2. URL示例
    ftp://ftp.is.co.za/rfc/rfc1808.txt
    
    3. URL缺点

    URL 表示的是实际的地址,而不是准确的名字。这就意味着 URL 会告诉你资源此时处于什么位置,它会为你提供特定端口上特定服务器的名字,告诉你在何处可以找到这个资源。这种方案的最大弊端在于,如果资源被移走了,URL 也就不再有效了。那时,它就无法对对象进行定位了。

    • URN (Uniform Resource Name)

    1. URN (Uniform Resource Name) is a URI in a standard format, referring to a resource without specifying its location or whether it exists.
    2. URN(统一资源名)是标准格式的URI,指的是资源,而不指定其位置或是否存在。
    3. URN是作为特定内容的唯一名称使用的,通过URN就可以用同一个名字通过多种网络访问协议来访问资源;
    4. 作为标识唯一书目的ISBN系统就是典型的URN适用范本;
      在这里插入图片描述
    • URI URL URN联系区别

    1. A URI can be further classified as a locator, a name, or both. The term “Uniform Resource Locator” (URL) refers to the subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism(e.g., its network “location”). The term “Uniform Resource Name”(URN) has been used historically to refer to both URIs under the “urn” scheme [RFC2141], which are required to remain globally unique and persistent even when the resource ceases to exist or becomes unavailable, and to any other URI with the properties of a name.
      An individual scheme does not have to be classified as being just one of “name” or “locator”. Instances of URIs from any given scheme may have the characteristics of names or locators or both, often depending on the persistence and care in the assignment of identifiers by the naming authority, rather than on any quality of the scheme. Future specifications and related documentation should use the general term “URI” rather than the more restrictive terms “URL” and “URN” [RFC3305].

      URI 可以进一步分为定位器、名称,或者二者兼具。术语“Uniform Resource Locator” (URL) 涉及的是 URI 的子集,除识别资源外,它还通过描述其最初访问机制(比如它的网络“位置”)来提供定位资源的方法。 术语“Uniform Resource Name” (URN) 在历史上曾用于引用“urn”方案 [RFC2141] 下的 URI,这个 URI 需要是全球惟一的,并且在资源不存在或不再可用时依然保持不变,对于其他任何拥有名称的一些属性的 URI,都需要使用这样的 URI。
      对于单独的方案,没有必要将其分为仅仅是一个 “名称”或者是一个“定位器”。 来自任意特定方案的 URI 实例可能有名称或定位器的特征,或两者兼而有之, 这通常取决于标识符分配中的持久性和命名机构对其关注程度, 而不取决于其他方案的质量。未来的规范和相关的文档应当使用通用术语“URI”,而不是使用有更多限制的条目“URL”和“URN” [RFC3305]。

    Web编码

    参考从原理上搞定编码(二)-- Web编码所写

    html页面编码

    当浏览器请求一个静态html页面时,服务器会将html页面的字节流通过网络传输给浏览器,浏览器再将字节流解码成相应的html文本字符,然后将html渲染出来。

    此流程中浏览器如何判断用什么编码格式去解码呢?

    在html的head标签中会有一个meta标签,charset属性如果指定为“UTF-8”浏览器就会用UTF-8解码html页面。
    问题是在浏览器解析< meta />标签获取页面编码前,浏览器是用什么解析< meta />标签的呢?
    因为html开头都是字母,基本不会存在ASCII码之外的字符,所以识别起来还是有难度的。

    测试代码,第5行和第6行,会根据不同的测试条件分别打开注释,具体打开哪个后边会有提示。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <!-- <meta charset="UTF-8"> -->
        <!-- <meta charset="GBK"> -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>UTF-8</title>
    </head>
    
    <body>
        <p>Get 请求</p>
        <form action="TestServlet" method="get">
            <input type="text" value="你好" name="txtKey" />
            <input type="submit" value="提交" />
        </form>
        <p>Post 请求</p>
        <form action="TestServlet" method="post">
            <input type="text" value="你好" name="txtKey" />
            <input type="submit" value="提交" />
        </form>
    </body>
    
    </html>
    
    </html>
    

    IDE是VS Code,浏览器是Chrome。项目结构如下,其中有两个html页面,"h5-编码UTF8.html"页面用utf-8编码存储,"h5-编码GBK.html"页面用GBK编码存储。两个页面的html代码都是上边给出的html代码。

    实验一: 在utf-8编码的html页面中指定不同的编码格式

    启动项目,用浏览器打开"h5-编码UTF8.html"的url,如下图所示,可以看出浏览器解析到标签中的utf-8编码,并用utf-8解码html页面,页面正确显示,如下图所示。
    01-UTF8中用UTF8编码
    如果在标签中指定页面编码为GBK,那么浏览器就用GBK解码,肯定就不能正确显示页面了,如下图所示,页面中文出现乱码。
    01-UTF8中用GBK编码
    所以如果想避免乱码的话,必须保证编解码格式统一

    实验二: 不指定页面编码的情况下测试不同的编码页面

    在这里插入图片描述
    在这里插入图片描述
    浏览器会根据文件的编码类型来选用对应的解码类型;

    实验三: 在一个html页面中指定两个不同的编码

    追加一点js代码

    html中追加:
    <script src="./test.js"></script>
    <div id='test'></div>
     
    js文件内容:
    document.addEventListener('DOMContentLoaded',function(){
        document.getElementById('test').innerHTML="<h1>我是中华小能手!</h1>";
    })
    

    03-混合字符编码
    从图中可以看出:

    1. 如果出现多个编码以第一个出现的为主。(两个< meta />标签)
    2. script标签的charset属性,决定了浏览器去加载完js,解析字节流时用的编码,如果script未设定charset属性,跟着页面的编码走;
    结论:编码的确认优先级
    1. User browser setting
      如果用户指定了编码,则按用户指定的编码进行解码。

    2. Byte order mark
      先对文件进行预解析,如果文件存在BOM(Byte Order Mark),则按BOM确定的编码解码。

    3. HTTP header
      如果HTTP响应头中存在编码信息,则按响应头中的编码进行解码。

    4. or depending on attribute order.

      先按浏览器的编码选择算法选择一个编码进行预解析,如果解析出标签中存在字符集设置,则按标签中的字符集进行解码。

    5. Browser default for the locale.
      按浏览器的默认编码

    常用API

    • characterSet

    语法:document.characterSet
    用法:只读属性,返回当前文档的字符编码;

    window.document.characterSet
    // "UTF-8"
    
    • encodedURI(URI)

    语法:encodedURI(URI)
    用法:

    1. encodedURI(URI)中的参数URI要是一个完整的URI,返回值是一个新字符串,表示提供的字符串编码为URI。即此方法适用于对整个URI统一进行编码处理,且携带的参数里明确不带有不可编码且容易引起歧义的字符,如果存在,需要使用encodeURIComponent
    2. encodeURI会替换所有的字符,但不包括以下字符:
      字母 数字 - _ . ! ~ * ’ ( ) ; , / ? : @ & = + $ #
    encodeURI('http://tingshuo\<what>//about{what}')
    // "http://tingshuo%3Cwhat%3E//about%7Bwhat%7D"
    
    encodeURI('http://tingshuo\<what>//about{what}?comment=Thyme &time=again')
    // "http://tingshuo%3Cwhat%3E//about%7Bwhat%7D?comment=Thyme%20&time=again"
    // 参数param的值本来为“Thyme &time=again”,结果因为“&”和“="符号不可
    以编码,产生了一个新的键值对,所以服务器得到两个键值对(一个键值对
    是comment=Thyme,另一个则是time=again),而不是一个键值对。
    
    • encodeURIComponent(str)

    语法:encodeURIComponent(str)
    用法:

    1. 对URI的组成部分进行编码。
    2. encodeURIComponent会替换所有的字符,但不包括以下字符:字母 数字 ( ) . ! ~ * ’ - _
    'http://tingshuo\<what>//about{what}?comment='+encodeURIComponent('Thyme &time=again')
    // "http://tingshuo<what>//about{what}?comment=Thyme%20%26time%3Dagain"
    
    • decodeURI(encodedURI)

    语法:decodeURI(encodedURI)
    用法:
    decodedURI(URI)中的参数URI要是一个完整的编码过的URI,返回值是将已编码URI中所有能识别的转义序列转换成原字符;

    • decodeURIComponent(encodedStr)

    语法:decodeURIComponent(encodedStr)
    用法:
    decodeURIComponent(encodedStr)中的参数encodedStr是编码后的部分URI,返回值是将已编码URI中所有能识别的转义序列转换成原字符;

    • escape(已废弃)

    请使用encodeURI和encodeURICompent代替

    参考

    从 URI 开始 #10
    分清 URI、URL 和 URN

    展开全文
  • 编码解码(字符集)

    2018-09-13 17:45:18
    通俗的说,按照何种规则将字符存储在计算机中,如’a’用什么表示,称为”编码”;反之,将存储在计算机中的二进制数解析显示出来,称为”解码”,如同密码学中的加密和解密。在解码过程中,如果使用了错误的解码...

    1.基础概念

    计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如’a’用什么表示,称为”编码”;反之,将存储在计算机中的二进制数解析显示出来,称为”解码”,如同密码学中的加密和解密。在解码过程中,如果使用了错误的解码规则,则导致’a’解析成’b’或者乱码。

    1.1 字符集

    字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

    1.2 字符编码

    字符编码(Character Encoding):即一套法则,在符号集合与数字系统之间建立对应关系。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用数字(0/1)来存储和处理信息的。因此字符编码就是将符号转换为计算机可以存储的数字。

    2.基础知识

    常见字符集名称:ASCII字符集、GB2312字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。

    2.1 ASCII字符集&编码

    ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以显示其他西欧语言。它是现今最通用的单字节编码系统。

    1) ASCII字符集:

    ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。

    2) ASCII编码:

    ASCII编码:将ASCII字符集转换为计算机系统可以存储的数字的编码规则。使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。

    2.2. GBXXXX字符集&编码

    计算机发明之初,只用应用于美国及西方一些发达国家,ASCII能够很好的满足需求。但是当天朝也有了计算机之后,为了显示中文,必须设计一套用于将汉字转换为计算机可以存储的数字的编码。

    GB 2312 标准共收录 6763 个汉字,GB 2312 对任意字符都采用双字节表示
    GBK 共收入 21886 个汉字和图形符号,GBK 对任意字符都采用双字节表示
    GB 18030 共收录汉字70244个,GB 18030 编码是一二四字节变长编码。其单字节,与 ASCII 编码兼容。
    注:GBK兼容GB2312,GB18030兼容GBK

    2.3 Unicode字符集&编码

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案,记录着世界上所有字符对应的一个数字。

    1) UTF-8编码

    UTF-8 是目前互联网上使用最广泛的一种 Unicode 编码方式,它的最大特点就是可变长。它可以使用 1 - 4 个字节表示一个字符,根据字符的不同变换长度。

    UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:
    Unicode编码(十六进制) UTF-8字节流(二进制)
    000000—00007F 0xxxxxxx
    000080—0007FF 110xxxxx 10xxxxxx
    000800—00FFFF 1110xxxx 10xxxxxx 10xxxxxx
    010000—10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00—0x7F之间的字符,UTF-8编码与 ASCII 编码完全相同。

    对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 10,剩下的二进制位则使用这个字符的 Unicode 码点来填充。
    例1:“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

    2.4 Base64字符集&编码

    Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
    这里写图片描述

    1) 数据正好3字节

    例如: “ABC”
    UTF-8编码后: 01000001 01000010 01000011
    转换 : 00010000 00010100 00001001 00000011
    结果: “QUJD”

    2) 数据剩余2字节

    例如: “AB”
    UTF-8编码后: 01000001 01000010
    转换 : 00010000 00010100 00001000
    结果: “QUI=”

    2个字节16位,base64进行编码时,每6位一组,最后一组只有4位,右侧需要用”00”补齐,编码后的结果添加一个”=”

    3) 数据剩余1字节

    例如: “A”
    UTF-8编码后: 01000001
    转换 : 00010000 00010000
    结果: “QQ==”

    1个字节8位,base64进行编码时,每6位一组,最后一组只有2位,右侧需要用”0000”补齐,编码后的结果添加一个”==”

    展开全文
  • LZW编解码详解

    2020-05-15 14:22:23
    最近在看LZW编码解码,正好看到一篇好文章,在此记录: 转自:https://segmentfault.com/a/1190000011425787 最近整理Github上以前胡乱写的代码,发现自己还写过压缩算法,大概是不知道什么时候用来练手的。里面...

    最近在看LZW编码和解码,正好看到一篇好文章,在此记录:

    转自:https://segmentfault.com/a/1190000011425787

    最近整理Github上以前胡乱写的代码,发现自己还写过压缩算法,大概是不知道什么时候用来练手的。里面我实现了哈夫曼树,LZW字典和算数编码三种压缩算法,时隔几年几乎没什么印象了,尤其是后两种连原理都基本忘了,所以把它们拎出来整理一下,也算是逼自己做个回忆。

    本篇先讲LZW算法,Wiki里给出的介绍和样例其实还不错,不过我在网上并没有找到很多其它的比较清晰的讲解,很多都是贴贴代码和流程图了事,所以这里我用我个人的理解,把LZW的原理再整理一遍。

    一个简单的例子

    LZW编码 (Encoding) 的核心思想其实比较简单,就是把出现过的字符串映射到记号上,这样就可能用较短的编码来表示长的字符串,实现压缩,例如对于字符串:

    ABABAB

    可以看到子串AB在后面重复出现了,这样我们可以用一个特殊记号表示AB,例如数字2,这样原来的字符串就可以表示为:

    AB22

    这里我们称2是字串AB的记号(Symbol)。那么A和B有没有记号来表示?当然有,例如我们规定数字0表示A,数字1表示B。实际上最后得到的压缩后的数据应该是一个记号流 (Symbol Stream) :

    0122

    这样我们就有一个记号和字符串的映射表,即字典 (Dictionary) :

    Symbol String
    0 A
    1 B
    2 AB

    有了压缩后的编码0122,结合字典,就能够很轻松地解码 (Decoding) 原字符串ABABAB。

    当然在真正的LZW中A和B不会用数字0和1表示,而是它们的ASCII值。实际上LZW初始会有一个默认的字典,包含了所有256个8bit字符,单个字符的记号就是它自身,用数字表示就是ASCII值。在此基础上,编码过程中加入的新的记号的映射,从256开始,称为扩展表(Extended Dictionary)。在这个例子里是为了简单起见,只有两个基础字符,所以规定0表示A,1表示B,从记号2开始就是扩展项了。

    字典的生成

    这里有一个问题:为什么第一个AB不也用2表示?即表示为222,这样不又节省了一个记号?这个问题实际上引出的是LZW的一个核心思想,即压缩后的编码是自解释 (self-explaining) 的。什么意思?即字典是不会被写进压缩文件的,在解压缩的时候,一开始字典里除了默认的0->A和1->B之外并没有其它映射,2->AB是在解压缩的过程中一边加入的。这就要求压缩后的数据自己能告诉解码器,完整的字典,例如2->AB是如何生成的,在解码的过程中还原出编码时用的字典。

    用上面的例子来说明,我们可以想象ABABAB编码的过程:

    1. 遇到A,用0表示,编码为0。
    2. 遇到B,用1表示,编码为1。
    3. 发现了一个子串AB,添加映射2->AB到字典里。
    4. 后面又出现了AB子串,都用2来编码。

    以上过程只是一个概述,并非真正LZW编码过程,只是为了表示它的思想。可以看出最前面的A和B是用来生成表项2->AB的,所以它们必须被保留在压缩编码里,作为表项2->AB生成的“第一现场”。这样在解码0122的时候,解码器首先通过01直接解析出最前面A和B,并且生成表项2->AB,这样才能将后面出现的2都解析为AB。实际上解码器是自己还原出了编码时2->AB生成的过程。

    编码和解码都是从前往后步步推进的,同时生成字典,所以解码的过程也是一个不断还原编码字典的过程。解码器一边解码,向后推进,一边在之前已经解出的原始数据上重现编码的过程,构建出编码时用的字典。

    LZW算法详解

    下面给出完整的LZW编码和解码的过程,结合一个稍微复杂一点的例子,来说明LZW的原理,重点是理解解码中的每一步是如何对应和还原编码中的步骤,并恢复编码字典的。

    编码算法

    编码器从原字符串不断地读入新的字符,并试图将单个字符或字符串编码为记号 (Symbol)。这里我们维护两个变量,一个是P (Previous),表示手头已有的,还没有被编码的字符串,一个是C (current),表示当前新读进来的字符

     1. 初始状态,字典里只有所有的默认项,例如0->a,1->b,2->c。此时P和C都是空的。
     2. 读入新的字符C,与P合并形成字符串P+C。
     3. 在字典里查找P+C,如果:
        - P+C在字典里,P=P+C。
        - P+C不在字典里,将P的记号输出;在字典中为P+C建立一个记号映射;更新P=C。
     4. 返回步骤2重复,直至读完原字符串中所有字符。

    以上表示的是编码中间的一般过程,在收尾的时候有一些特殊的处理,即步骤2中,如果到达字符串尾部,没有新的C读入了,则将手头的P对应的记号输出,结束。

    编码过程的核心就在于第3步,我们需要理解P究竟是什么。P是当前维护的,可以被编码为记号的子串。注意P是可以被编码为记号,但还并未输出。新的字符C不断被读入并添加到P的尾部,只要P+C仍然能在字典里找到,就不断增长更新P=P+C,这样就能将一个尽可能长的字串P编码为一个记号,这就是压缩的实现。当新的P+C无法在字典里找到时,我们没有办法,输出已有的P的编码记号,并为新子串P+C建立字典表项。然后新的P从单字符C开始,重新增长,重复上述过程。

    这里用一个例子来说明编码的过程,之所以用小写的字符串是为了和P,C区分。

    ababcababac

    初始状态字典里有三个默认的映射:

    Symbol String
    0 a
    1 b
    2 c

    开始编码:

    Step P C P+C P+C in Dict ? Action Output
    1 - a a Yes 更新P=a -
    2 a b ab No 添加3->ab,更新P=b 0
    3 b a ba No 添加4->ba,更新P=a 1
    4 a b ab Yes 更新P=ab -
    5 ab c abc No 添加5->abc,更新P=c 3
    6 c a ca No 添加6->ca,更新P=a 2
    7 a b ab Yes 更新P=ab -
    8 ab a aba No 添加7->aba,更新P=a 3
    9 a b ab Yes 更新P=ab -
    10 ab a aba Yes 更新P=aba -
    11 aba c abac No 添加8->abac,更新P=c 7
    12 c - - - - 2

    注意编码过程中的第3-4步,第7-8步以及8-10步,子串P发生了增长,直到新的P+C无法在字典中找到,则将当前的P输出,P则更新为单字符C,重新开始增长。

    输出的结果为0132372,完整的字典为:

    Symbol String
    0 a
    1 b
    2 c
    3 ab
    4 ba
    5 abc
    6 ca
    7 aba
    8 abac

    这里用一个图来展示原字符串是如何对应到压缩后的编码的:
    图片

    --

    解码算法

    解码的过程比编码复杂,其核心思想在于解码需要还原出编码时的用的字典。因此要理解解码的原理,必须分析它是如何对应编码的过程的。下面首先给出算法:

    解码器的输入是压缩后的数据,即记号流 (Symbol Stream)。类似于编码,我们仍然维护两个变量pW (previous word) 和cW (current word),后缀W的含义是word,实际上就是记号 (Symbol),一个记号就代表一个word,或者说子串。pW表示之前刚刚解码的记号;cW表示当前新读进来的记号。

    注意cW和pW都是记号,我们用Str(cW)和Str(pW)表示它们解码出来的原字符串。

    1. 初始状态,字典里只有所有的默认项,例如0->a,1->b,2->c。此时pW和cW都是空的。
    2. 读入第一个的符号cW,解码输出。注意第一个cW肯定是能直接解码的,而且一定是单个字符。
    3. 赋值pW=cW。
    4. 读入下一个符号cW。
    5. 在字典里查找cW,如果:
       a. cW在字典里:
         (1) 解码cW,即输出 Str(cW)。
         (2) 令P=Str(pW),C=Str(cW)的**第一个字符**。
         (3) 在字典中为P+C添加新的记号映射。
       b. cW不在字典里:
         (1) 令P=Str(pW),C=Str(pW)的**第一个字符**。
         (2) 在字典中为P+C添加新的记号映射,这个新的记号一定就是cW。
         (3) 输出P+C。
    6. 返回步骤3重复,直至读完所有记号。

    显然,最重要的是第5步,也是最难理解的。在这一步中解码器不断地在已经破译出来的数据上,模拟编码的过程,还原出字典。我们还是结合之前的例子来说明,我们需要从记号流

    0 1 3 2 3 7 2

    解码出:

    a b ab c ab aba c

    这里我用空格表示出了记号是如何依次对应解码出来的子串的,当然在解码开始时我们根本不知道这些,我们手里的字典只有默认项,即:

    Symbol String
    0 a
    1 b
    2 c

    解码开始:
    首先读取第一个记号cW=0,解码为a,输出,赋值pW=cW=0。然后开始循环,依此读取后面的记号:

    Step pW cW cW in Dict ? Action Output
    1 0 1 Yes P=a,C=b,P+C=ab,添加3->ab b
    2 1 3 Yes P=b,C=a,P+C=ba,添加4->ba ab
    3 3 2 Yes P=ab,C=c,P+C=abc,添加5->abc c

    好,先解码到这里,我们已经解出了前5个字符 a b ab c。一步一步走下来我们可以看出解码的思想。首先直接解码最前面的a和b,然后生成了3->ab这一映射,也就是说解码器利用前面已经解出的字符,如实还原了编码过程中字典的生成。这也是为什么第一个a和b必须保留下来,而不能直接用3来编码,因为解码器一开始根本不知道3表示ab。而第二个以及以后的ab就可以用记号3破译出来,因为此时我们已经建立了3->ab的关系。

    仔细观察添加新映射的过程,就可以看出它是如何还原编码过程的。解码步骤5.a中,P=Str(pW),C=Str(cW)的第一个字符,我们可以用下图来说明:
    图片描述

    注意P+C构成的方式,取前一个符号pW,加上当前最新符号cW的第一个字符。这正好对应了编码过程中遇到P+C不在字典中的情况:将P编码为pW输出,并更新P=C,P从单字符C开始重新增长。

    到目前为止,我们只用到了解码步骤5.a的情况,即每次新读入的cW都能在字典里找到,只有这样我们才能直接解码cW输出,并拿到cW的第一个字符C,与P组成P+C。但实际上还有一种可能就是5.b中的cW不在字典里。为什么cW会不在字典里?回到例子,我们此时已经解出了5个字符,继续往下走:

    Step pW cW cW in Dict ? Action Output
    4 2 3 Yes P=c,C=a,P+C=ca,添加6->ca ab
    5 3 7 No P=ab,C=a,P+C=aba,添加7->aba aba
    6 7 2 Yes P=aba,C=c,P+C=abac,添加8->abac c

    好到此为止,后面的 ab aba c 也解码出来了,解码过程结束。这里最重要的就是Step-5,新读入一个cW为7,可7此时并不在字典里。当然我们事实上知道7最终应该对应aba,可是解码器应该如何反推出来?

    为什么解码进行到这一步7->aba还没有被编入字典?因为解码比编码有一步的延迟,实际上aba正是由当前的P=ab,和那个还未知的cw=7的第一个字符C组成的,所以cW映射的就是这个即将新加入的子串P+C,也因此cW的第一个字符就是pW的第一个字符a,cW就是aba。

    我们看到解码器在这里做了一个推理,既然cW到目前为止还没有被加入字典,可解码却偏偏遇到了,说明cW的映射并不是很早之前加入的,而是就在当前这一步。对应到编码的过程,就是新的cW映射,即7->aba刚被写进字典,紧接着后面的一个字串就用到了它。读者可以对照后半部分 ab aba c 编码的过程,对比解码过程反推,理解它的原理。这也是解码算法中最难的部分。

    总结

    好了,LZW的编码和解码过程到此就讲解完毕了。其实它的思想本身是简单的,就是将原始数据中的子串用记号表示,类似于编一部字典。编码过程中如何切割子串,建立映射的方式,其实并不是唯一的,但是LZW算法的严格之处在于,它提供了一种方式,使得压缩后的编码能够唯一地反推出编码过程中建立的字典,从而不必将字典本身写入压缩文件。试想,如果字典也需要写入压缩文件,那它占据的体积本身就会很大,可能到最后起不到压缩的效果。

    我用C++实现了一下LZW,详见github:https://github.com/Wzing0421/LZW

    展开全文
  • 关于解码编码

    2018-03-08 20:47:07
    上网查过之后现在终于明白编码解码到底是怎么一回事了。下面请听我娓娓道来。先看一段代码:import requests url = 'http://www.baidu.com' r = requests.get(url) text = r.text print(text)运行一下发现乱码了:...

    今天在看书的时候看到编码的时候整个人脑子都被浆糊了一样,感觉真的很烦。上网查过之后现在终于明白编码与解码到底是怎么一回事了。下面请听我娓娓道来。

    先看一段代码:

    import requests
    url = 'http://www.baidu.com'
    r = requests.get(url)
    text = r.text
    print(text)

    运行一下发现乱码了:


    我的ide是默认编码为utf-8的,那么为什么还会出现乱码呢。原因在于我们的网站时通过gzip压缩过的,所以我们必须先进行解压。说解压前必须了解r.text和r.content之间的区别。

    r.text是字符串方式的响应体

    r.content是字节方式的响应体

    所以当我们用r.text进行输出的时候当然是乱码的,在解压前你是没办法输出中文的。

    然而,我们的r.content是可以解压gzip和deflate压缩的,因此我们看下面一段代码

    import requests
    url = 'http://www.baidu.com'
    r = requests.get(url)
    text = r.content
    print(text)
    

    再运行一下看一下结果:


    我们发现变成这样了,那么这些东西是什么呢,其实这些东西都是Unicode编码形式的样子,都是一些十六进制的文本,

    也就是说我们通过r.content解压缩后我们的页面变成了Unicode编码了,可是我们的最终目的是输出中文呀,所以我们的最后

    一步是进行解码。看一下代码

    import requests
    url = 'http://www.baidu.com'
    r = requests.get(url)
    text = r.content
    print(text.decode('utf-8'))

    其实到这一步的时候,我整个人就懵了,我心想如果要改成中文输出的话不是应该用encode来进行编码吗,怎么是decode,

    然后我百思不得其解,遂上网百度了一下,发现了如下两句话。

    1.将字符转换为字节的方式称为编码

    2.将字节转换为字符的方式称为解码

    OK,一切到这里所有疑惑都解决了,原来从一开始我就对这两个词存在着理解上的错误。

    decode('utf-8')的意思就是将当前的unicode编码转换成utf-8编码,最后看一下结果


    谢谢各位观看。

    展开全文
  • 几种编解码算法

    2019-04-16 18:28:45
    22.05KHz:无线电广播; 44.1KHz:音频 CD,MP3等; 48KHz:miniDV、数字电视、DVD、电影和专业音频。
  • 编码解码

    2017-03-15 21:52:32
    编码:  计算机中存储的都是二进制,但是要显示的时候,就是我们看到的却可以有中国 ,a 1等字符 计算机中是没有存储字符的,但是我们却看到了。计算机在存储这些信息的时候,根据一个有规则的编号,当用户...
  • 编码解码

    2019-04-20 20:34:37
    概念 字符的三种形态 ... 编码:将字符转为字节序列(abcdefg-------------> 0101010100101010010) 解码:将字节序列转为字符(10010101010100010010110...一个web项目中的编解码历程 这个是个简单的场景:中间的...
  • H.265仍然采用混合编解码编解码结构域H.264基本一致, 主要的不同在于: 1.编码块划分结构:采用CU (CodingUnit)、PU(PredictionUnit)和TU(TransformUnit)的递归结构。 2.基本细节:各功能块的内部细节有...
  • 解码编码 解码:就是把能看得懂的转成二进制字节码文件(字节-------->字符) 编码:就是把二进制字节码文件转成能看得懂的文字(字符-------->字符节) 编码表:字典。人们生活中常用的字符与计算机二进制之间...
  • 音频编解码,录制铃音,增加混音效果,目前只支持编解码MP3格式文件。将音频文件放到SDCard/RecordMixMp3/music下,进入软件,点击演唱就可以了。 本项目用到 lame、libmad,ting 源代码+文件+apk:伴唱混音.zip
  • 硬件编解码介绍 音视频编解码的两种方式  对视频数据编解码一般有两种方式:  1、软件的方式。使用常规的x264、x265等软件编解码器对数据进行处理,优点是灵活,可以根据需要进行定制,缺点是速度...
  • 音频编解码原理

    2017-12-11 11:25:11
    一般常见的情况 是,依赖嵌入式 ARM 或 DSP 的处理能力,通过定点 或浮点程序实现音频编解码过程。 实例说明  音频编解码常用的实现方案有三 种。  第一种就是采用专用的音频芯片对 语音信号进行
  • netty的编解码器介绍

    2018-08-22 10:10:41
    3. Encoder 编码器netty提供了强大的编解码器框架,使得我们编写自定义的编解码器很容易,也容易封装个重用。在网络应用中需要实现某种编解码器,将原始字节数据与自定义的消息对象进行互相转换。网络中都是以字节码...
  • ​ Netty提供了编解码器框架,使得编写自定义的编解码器很容易,并且也很容易重用和封装。本章讨论Netty的编解码器框架以及使用。 7.1 编解码器Codec ​ 编写一个网络应用程序需要实现某种编解码器,编解码器的作用...
  • 完全免费 运行环境:Vista, Win2003, WinXP, Win2000 添加时间:2008-7-1 Xvid MPEG-4 Video Codec (XviD v1.1.3 Final 汉化版) xvid 编解码器软件简介XviD是一个开放源码的MPEG-4多媒体编码解码器,它...
  • 编解码:十六进制编解码 信息有多种表现形式:二进制、十进制、十六进制、字符串… 在计算机中,信息是以二进制的形式来表现。 可以人为定义:0就是假,1就是真,等等。 所谓编解码,是将一种数据以另一种形式来...
  • 编解码学习笔记(一):基本概念 编解码学习笔记(二):codec类型 编解码学习笔记(三):Mpeg系列——Mpeg 1和Mpeg 2 编解码学习笔记(四):Mpeg系列——Mpeg 4 编解码学习笔记(五):Mpeg系列——AAC音频 ...
  • Netty编解码框架分析

    2018-05-30 15:14:47
    编解码技术通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输、数据持久化或者其它用途。反之,解码(Decode)/反序列化(deserialization)把从网络、磁盘等...
  • 各种音视频编解码学习详解  编解码学习笔记(一):基本概念   媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、...
  • 昨天介绍了视频编解码的原理,内容实属困难啊!脑细胞死一片。。。今天来点简单的,写完就去吃午饭! 主流的视频编码算法 MPEG-4和H.264区别 H.264特点 视频解码的原理及主流解码器 解码原理 专用芯片型和可编程型...
1 2 3 4 5 ... 20
收藏数 313,927
精华内容 125,570
关键字:

编码解码