0%

概念

  • 情感上:是蓝色的、忧伤的、哀愁的,用于抒发工作、生活、离别等等忧郁情怀的音乐
  • 伴奏上:它们的伴奏往往不那么强烈甚至只是吉他或者口琴伴奏
  • 作用上:是一种情绪的宣泄,所以它的精神就在于自由、无拘无束的

歌曲

  • 罗列
  • 数据对比
  • 分析总结

罗列以下5种常用算法

  • gzip
  • deflate
  • LZO
  • Snappy
  • HPACK(http2用于标头压缩)

测试数据对比

  • 对比维度分别有压缩率、压缩速率、解压速率、准确率四个维度

对结果进行分析总结

常见的图片格式

  • JPEG, a lossy format compression, best for photographic and complex images. But the lossy part is means it’s awful for some kinds of image,especially simple text
  • GIF is lossless, and therefore good for text - but can only show 256 colors per image
  • PNG is lossless format created to replace GIF. It can show more than 256 colors in an image

那么以上图片到底有哪些优化呢?

JPEG2000

相较于JPEG压缩率更高,但由于计算复杂度高(其中涉及了小波变换)编解码速率要相对慢10倍左右,以及设计专利费问题,所以只是在小范围领域中大规模应用,比如数字影院(DCI规范要求Motion JPEG-2000),网络地图等。 目前仅safari浏览器支持,其他Browsers需要装插件查看。

BGP

BGP作为HEVC(将来可能会取代目前主流的视频编码规范H.264)的 Intra-Frame,采用先进的图像压缩协议,其有损压缩率是图片编码格式中最高且质量高的。对于业界几大巨头Mozilla、微软、谷歌、苹果,由于苹果支持BGP会增加成本而且其他三家公司都自己的图像压缩技术沉淀,BGP能不能流行还不好说。

JPEG-XR

微软图像压缩技术,同样比传统JPEG压缩率高,成像质量高。仅IE支持

webP

谷歌图像压缩技术,webM(谷歌的视频格式)的intra frame。由于谷歌有Android,相对其他公司更具竞争力,在谷歌生态中已经有90%以上的覆盖率了。

mozJPEG

Mozilla的图像压缩技术,仅FireFox支持

SSIM值对比

  • 不同压缩技术下每像素点压缩前后的SSIM值(结构相似度)多曲线图

图片对比(JPEG,webP)

一张3832 * 2554尺寸的高清大图(源自momentum),有1.3M,转换为webp后是不到1.1M。webp相对jpeg的压缩率高15%左右,且压缩前后质量的损耗人眼无感知

总结

一个图片格式能否流行基于其压缩率、编解码效率、计算复杂度等,取决于专利。

主要内容有以下几点

  • http1.0与http1.1中存在的主要缺陷
  • SPDY
    • SPDY基础功能
    • SPDY高级功能
  • http2
    • 概述
    • 二进制分帧层
    • 数据流、消息和帧
    • 请求与响应复用
    • 数据流优先级
    • 每个来源一个连接
    • 流控制
    • 标头压缩
  • 如何使用Node搭建http2的web服务

http1.0与http1.1中存在的主要缺陷

在http1.0中存在的最主要的两个问题分别是链路无法复用以及HOLB(列头阻塞)。 链路无法复用直接导致了每一次请求都需要重新经历三次握手建立TCP连接与慢启动,三次握手无疑会增加大量延迟时间,这在高延迟的场景以及移动端叫为明显。http1.1中部分resolve了这个问题。 Head Of Line Blocking在第一个请求未得到响应前,后续请求只能排队等待,导致网络带宽无法被充分利用。http1.1部分resolve了这个问题。 能够将多个http请求借用一条TCP链路发出,也就是pipelining。然而没有根治,比如只有HEAD,GET,OPTIONS请求才可复用链路,POST请求依旧无法使用,因为可能存在请求间存在依赖关系;亦或是服务端遵循FIFO原则依次响应,或其它缺陷。 无服务端推送

SPDY

http1.x依然存在两个痛点,即延迟与安全性,直到2012年google提出了SPDY方案,通过多路复用、请求优先级、header压缩等功能来解决http1.x的遗留问题,但是google决定在2016年不再继续支持SPDY的开发。就在这个SPDY催化剂的作用下,http2应运而生,其实http2就是以SPDY为原型进行讨论和制定的 为降低延迟,C端的单连接单请求,server端的FIFO响应队列都是延迟的大头 http最初设计就是C端发请求,server端响应,server无法主动push内容到C端 压缩http header,由于业务需求膨胀导致cookie与UA体积增大,很容易达到1kb大小,由于http是无状态特性,header必须每次request都需要重复携带,较为耗费流量。 SPDY设计的层级关系为

SPDY基础功能

多路复用(multiplexing)。多路复用通过多个请求stream并标识唯一id共享一个tcp连接的方式,解决了http1.x holb的问题,降低了延迟同时提高了带宽利用率 请求优先级(request prioritization)。多路复用会带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会有限得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容 header压缩。SPDY对header的压缩率可以达到80%以上,低带宽环境下效果较大。通常丢包率越大,影响越大

SPDY高级功能

server推送(server push)。开启server push之后,server通过X-Associated-Content header告知C端会有新的内容推送过来。 server暗示(server hint)。sever hint不会主动push内容,只是告诉有心的内容产生,内容的下载还是需要C端主动发起请求。server hint通过X-Subresources header来通知,可用于服务端导出的场景。

HTTP2

概述

HTTP/2 可以让我们的应用更快、更简单、更稳定 - 这几词凑到一块是很罕见的!HTTP/2 将很多以前我们在应用中针对 HTTP/1.1 想出来的“歪招儿”一笔勾销,把解决那些问题的方案内置在了传输层中。不仅如此,它还为我们进一步优化应用和提升性能提供了全新的机会! HTTP/2 的目的是通过支持完整的请求与响应复用来减少延迟,通过有效压缩 HTTP 标头字段将协议开销降至最低,同时增加对请求优先级和服务器推送的支持。为达成这些目标,HTTP/2 还给我们带来了大量其他协议层面的辅助实现,例如新的流控制、错误处理和升级机制。上述几种机制虽然不是全部,但却是最重要的,每一位网络开发者都应该理解并在自己的应用中加以利用。 HTTP/2 没有改动 HTTP 的应用语义。HTTP 方法、状态代码、URI 和标头字段等核心概念一如往常。不过,HTTP/2 修改了数据格式化(分帧)以及在客户端与服务器间传输的方式。这两点统帅全局,通过新的分帧层向我们的应用隐藏了所有复杂性。因此,所有现有的应用都可以不必修改而在新协议下运行。

二进制分帧层

http2所有性能增强的核心在于新的二进制分帧层,它定义了如何封装http消息并在客户端与服务器之间传输。 这里所谓的层不是在网络协议协议栈中又新增了一层,而是指一种新的编码机制:http的语义都不受影响,不同的是传输期间对他们的编码方式改变了。http1.x采用换行符分割的文本编码,而http2将所传输信息分割成更小的消息和帧,并用二进制编码。 这一切的改变对应用层透明。

数据流、消息和帧

新的二进制分帧层机制改变了客户端与服务器之间交换数据的方式。其中引入了三个概念用于理解:

  • 数据流(data stream): 已建立的连接内的双向字节流,用于承载一条或多条消息
  • 消息(message):与逻辑请求和响应相对应的完整的一系列帧
  • 帧(frame): http2通信的最小单位,每个帧都包含帧头,因为至少会标识出所属数据流

这些概念的关系如下:

  • 所有通信都在一个TCP连接上完成,此连接可以承载任意数量的双向数据流(可以断定网页仅需一个TCP连接)
  • 每个数据流都有一个唯一标识符和可选的优先级信息,用于承载双向消息(前端也许可以通过webAPI指定某次HTTP请求的优先级)
  • 每条消息都是一条逻辑HTTP消息,包含一个或多个帧(推断可能是利用TCP的分片传输机制)
  • 帧是最小的通信单位,承载着特定类型的数据,例如HTTP标头、消息负载等等。来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。(类似TCP分片传输机制)

简而言之,http2将http协议通信分解为二进制编码帧的交换,这些帧对应着特定数据流中的消息。所有这些都在一个TCP连接内复用。这是http2协议所有其他功能和性能优化的基础。

请求与响应复用

在HTTP/1.x中,如果客户端想要发起多个并行请求以提升性能,则必须使用多个TCP连接。这是http/1.x的交付模型,该模型可以保证每个连接每次只交付一个响应(响应排队)。更糟糕的是,这种模型也会导致队首阻塞(HoLB),从而导致底层TCP连接利用率底下。 http2中的新的二进制分帧层突破了这些限制,实现了完整的请求和响应复用:client和server可以将http消息分解为互不依赖的帧,然后交错发送,最后再另一端重组。 快照捕捉了同一个连接内多个并行的数据流。客户端正在向服务器传输一个DATA帧(数据流5),与此同时,服务器正在向客户端交错发送数据流1和数据流3的一系列帧。因此,一个连接上同时有三个并行数据流。 将http消息分解为独立的帧,交错发送,然后在另一端重组是http2的最重要的一项增强。Actually,这个机制会在整个网络技术栈中引发一系列连锁反应,从而带来巨大的性能提升,让我们可以:

  • 并行交错的发送多个请求,请求之间互不影响
  • 并行交错的发送多个响应,响应之间互不干扰
  • 公用一个连接发送多个请求以及响应
  • 不必再为绕过http1.x限制而做很多工作(例如级联文件、image sprites、域名分片)
  • 消除不必要的延迟和提高现有网络容量的利用率,从而减少页面加载时间

http2中的新二进制分帧层解决了http1.x中存在的队首阻塞问题,也消除了并行处理和发送请求及响应时对多个连接的依赖。结果,应用速度更快、开发更简单、部署成本更低。

数据流优先级

将http消息分解为多个独立的帧之后,我们就可以复用多个数据流中的帧,客户端和服务器交错发送和传输这些帧的顺序就成为关键的性能决定因素。为了做到这一点,http2标准允许每个数据流都有一个关联的权重和依赖关系:

  • 可以向每个数据流分配一个介于1至256之间的整数
  • 每个数据流与其他数据流之间可以存在显式依赖关系

数据流依赖关系和权重的组合让客户端可以构建和传递“优先级树”,表明它倾向于如何接收响应。反过来,服务器可以使用此信息通过控制CPU、内存和其他资源的分配设定数据流处理的priority,在资源数据可用之后,带宽分配可以确保将高priority响应以最优方式传输至客户端。 http2内部的数据流依赖关系通过将另一个数据流的唯一标识符作为父项引用进行声明;如果忽略标识符,相应数据流将依赖于“根数据流”。声明数据流依赖关系指出,应尽可能先向父数据流分配资源,然后再向其依赖项分配资源。(此处示例图片非常清晰,不赘述了) 如上图所示,数据流依赖关系与权重的组合明确表达了资源优先级,这是一种用于提升浏览器性能的关键功能,网络中拥有多种资源类型,它们的依赖关系和权重各不相同。不仅如此,http2协议还允许客户端随时更新这些priority,进一步优化浏览器性能。换句话说,我们可以根据用户互动和其他信号更改依赖关系和重新分配权重。

注:数据流依赖关系和权重的组合表示传输优先级,而不是要求,因此不能保证特定的处理或传输顺序。即,客户端无法强制服务器通过数据流优先级以特定顺序处理数据流。尽管这看起来违反直觉,但却是一种不必要行为。我们不希望在优先级较高的资源受阻时,还阻止服务器处理优先级较低的资源。

每个来源一个链接

有了新的分帧机制后,http2不再依赖多个TCP连接去并行复用数据流;每个数据都拆分成很多帧,而这些帧可以交错,还可以分别设定优先级。因此,所有http2连接都是永久的,而且仅需要每个来源一个连接,随之带来诸多性能优势。 大多数http传输是短暂而急促的,而TCP则针对长时间的批量数据传输进行了优化。通过重用相同的连接,http2既可以有效的利用每个TCP连接,也可以整体降低协议开销。不仅如此,使用更少的连接还可以减少占用的内存和处理空间,也可以缩短完整连接路径(即客户端、可信中介和源服务器的路径),这降低了整体运行成本并提高了网络利用率和容量。因此,迁移到http2不仅可以减少网络延迟,还有助于提高通量和降低运行成本。

注:连接数量减少对提升https部署的性能来说是一项特别重要的功能:可以减少开销较大的TLS连接数、提升会话重用率,以及整体上减少所需的客户端和服务器资源

流控制

流控制是一种阻止发送方向接收方发送大量数据报文的机制,以免超出后者的需求或者处理能力:发送方可能非常繁忙、处于较高负载之下,也可能仅仅希望为特定数据流分配固定量的资源。例如,客户端可能请求了一个具有较高优先级的大型视频流,但是用户已经暂定视频,客户端现在希望暂停或限制从服务器传输,以免提取与缓冲不必要的数据。再比如,一个代理服务器可能具有较快的下游连接和较慢的上游连接,并且也希望调节下游连接传输数据的速度以及匹配上游连接的速度来控制其资源利用率 这跟TCP流控制原理基本相同。不过,由于http2数据流在一个TCP连接内复用,TCP流控制既不够精细,也无法提供必要的应用级API来调节各个数据流的传输。为了解决这一问题,http2提供了一组简单的构建块,这些构建块允许客户端和服务器实现其自己的数据流控制和连接级流控制:

  • 流控制具有方向性。每个接收方都可以根据自身需要选择为每个数据流和整个连接设置任意的窗口大小。
  • 流控制基于信用。每个接收方都可以公布其初始连接和数据流流控制窗口(以字节为单位),每当发送方发出DATA帧时都会减小,在接收方发出WINDOW_UPDATE帧时增大
  • 流控制无法停用。建立http2连接后,客户端将与服务器交换SETTINGS帧,这会在两个方向上设置流控制窗口。流控制窗口的默认值为65535字节,但是接收方可以设置一个较大的最大窗口大小(最大为2^31 - 1字节),并在接收到任意数据时通过发送WINDOW_UPDATE帧来维持这一大小
  • 流控制为逐跃点控制,而非端到端控制。即,可信中介可以使用它来控制资源使用,以及基于自身条件和启发式算法实现资源分配机制。

http2未指定任何特定算法来实现流控制。不过,它提供了简单的构建块并推迟了客户端和服务器实现,可以实现自定义策略来调节资源使用和分配,以及实现新传输能力,同时提升网络应用的实际性能和感知性能 例如,它允许浏览器提取图像预览或首次扫描结果,进行显示并允许其他高优先级提取继续,然后在更关键的资源完成加载后恢复提取

服务器推送

http2在应用层输出的最令人振奋的功能是,服务器可以对一个客户端请求发送多个响应。换句话说,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端明确的请求。

注:http2打破了严格的请求-响应语义,支持一对多和服务器发起的推送工作流,在浏览器内外开启了全新的互动可能性。这是一项使能功能,对我们思考协议、协议用途和使用方式具有重要的长期影响。

为什么在浏览器中需要此类机制呢?一个典型的网络应用包含多种资源,客户端需要检查服务器提供的文档才能逐个找到他们。那为什么不让服务器提前推送这些资源,从而减少额外的延迟时间呢?服务器已经知道客户端下一步要请求什么资源,这时候服务器推送可派上用场。 事实上,如果您在网页中内联过CSS、Javascript,或者通过data URLs内联过其他资源,那么您就已经亲身体验过server push了。对于将资源手动内联到文档中的过程,我们实际上是在将资源推送给客户端,而不是等待客户端请求。使用http2,我们不仅可以实现相同结果,还会获得其他性能优势。推送资源可以进行如下处理:

  • 由客户端缓存
  • 在不同页面之间重用
  • 与其他资源一起复用
  • 由服务器设定优先级
  • 被客户端拒绝

PUSH_PROMISE 101 所有服务器推送数据流都由PUSH_PROMISE帧发起,表明了服务器向客户端推送所述资源的意图,并且需要先于请求推送资源的响应数据传输。这种传输顺序非常重要:客户端需要了解服务器打算推送哪些资源,以免这些资源创建重复请求。满足此要求的最简单策略是先于父响应(即,DATA帧)发送所有PUSH_PROMISE帧,其中包含所承诺资源的http标头。 在客户端接收到PUSH_PROMISE帧后,它可以根据自身情况选择拒绝数据流(通过RES_STREAM帧)。(如果资源已经位于缓存中,可能会发生这种情况。)这是一个相对于http/1.x是必要的提升。相比之下,使用资源内联等同于“强制推送”:客户端无法选择拒绝、取消或单独处理内联的资源。 使用http2,客户端仍然完全掌控服务器推送的使用方式。客户端可以限制并行推送的数据流数量;调整初始流控制窗口以控制在数据流首次打开时推送的数据量;或完全停用服务器推送。这些优先级在http2连接开始时通过SETTINGS帧传输,可能随时更新。 推送的每个资源都是一个数据流,与内嵌资源部不同,客户端可以对推送的资源逐一复用、设定优先级和处理。浏览器强制执行的唯一安全限制是,推送的资源必须符合原点相同这一策略:服务器对所推内容必须具有权威性。

标头压缩

每个http传输都承载了一组标头,这些标头说明了传输的资源及其元属性。在http1.x中,此元数据始终以纯文本形式,通常会给每个传输增加500-800字节的开销。如果使用http Cookie,增加的开销有时候会达到上千字节。为了减少此功能开销和提升性能,http2使用HPACK压缩格式压缩请求和响应标头元数据,这种格式采用两种简单但是强大的技术:

  • 这种格式支持通过静态Huffman代码对传输的标头进行编码,从而减少了各个传输的大小。
  • 这种格式要求客户端和服务端同时维护和更新一个包含之前见过的标头字段的索引列表(换句话说,他可以建立一个共享的压缩上下文),此列表随后会用作参考,对之前传输的值进行有效编码

利用Huffman编码,可以在传输时对各个值进行压缩,而利用之前传输值的索引列表,我们可以通过对传输索引值的方式对重复值进行编码,索引值可用于有效查询和重构完整的标头键值对。 作为一种进一步优化方式,HPACK压缩上下文包含一个静态列表和动态列表:静态表在规范中定义,并提供了一个包含所有连接都可能使用的常用http标头字段的列表;动态表最初为空,将根据在特定连接内交换的值进行更新。因此,为之前未见过的值采用静态Huffman编码,并替换每一侧静态表或动态表中已存在的索引,可以减少每个请求的大小。

注:在http中,请求和响应标头字段的定义保持不变,仅有一些微小的差异:所有标头端名称均为小写,请求行现在拆分成各个:method、:scheme、:authority和:path伪标头字段。

HPACK的安全性和性能 早起版本的http和SPDY使用zlib(带有一个自定义字典)压缩有所http标头。这种方式可以将所传输标头数据的大小减小85% - 88%,显著减少了页面加载时间延迟。 然而2012年夏天,出现了针对TLS和SPDY压缩算法的“犯罪”安全攻击,此攻击会导致会话被劫持。于是,zlib压缩算法被HPACK替代,后者经过专门设计,可以解决发现的安全问题、实现起来也更搞笑和简单,当然,可以对http标头元数据进行良好压缩。

如何使用Node搭建http2的web服务

这里使用node v9+版本built-in的http2模块

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout localhost-privkey.pem -out localhost-cert.pem


const http2 = require('http2')
const fs = require('fs')

const server = http2.createSecureServer({
  key: fs.readFileSync(__dirname + '/../localhost-privkey.pem'),
  cert: fs.readFileSync(__dirname + '/../localhost-cert.pem')
})

server.on('error', err => console.errr(err))
server.on('socketError', err => console.error(err))

server.on('stream', (stream, headers) => {
  // 流是双工的
  stream.respond({
    'content-type': 'application/json',
    ':status': 200
  })
  for (const name in headers) {
    console.log(`${name} : ${headers[name]}`)
  }
  stream.end('{"name": "Cecil"}')
})

server.listen(8443)

然后使用node编写http2client或者在Chrome中输入https://localhost:8443访问服务 了解http2模块,请至node http2模块 使用http2开发业务,请至Fastify

本文节选自google web

目的

一般情况下,对数据做加密处理确保两点即可:1.有效性 2.完整性

基本概念

  • 初始向量(initialize vector)
  • PKCS

AES-128-CBC简单声明

  • AES-128-CBC是一种常用的分组对称加密算法,即用同一组key进行明文和密文的转换,以128bits为一组,也就是16Bytes,意思就是明文中的16Bytes为一组对应加密后的16Byte的密文
  • 若明文最后不足16Bytes,需要进行填充,通常采用PKCS#7进行填充。比如最后缺3Bytes,则填充6个0x03;若缺11Bytes,则填充22个0x0b
  • 若明文刚好为16Bytes,则最后要再加32个0x10作为一个分组。
  • key,IV长度均为16Bytes
  • CBC工作模式是:给定一个初始向量iv对第一分组进行加密,生成16Bytes密文作为下一分组的偏移向量递归进行加密,直到所有明文均已转换成密文为止

RSA简单声明

  • 对极大整数做因数分解的难度决定了RSA算法的可靠性。
  • CA一般采用2048bits长度密钥
  • 其运算速度大约为相同安全级别的对称算法的1/1000左右
  • RSA密钥长度随保密级别提高,增加更快(2的指数倍)

常用的加密手段

  1. 首先,peer1生成key以及iv,将明文用AES-128-CBC算法加密并用base64序列化密文,随后对key用私钥RSA算法加密,也就是数字签名,随后通过网络将密文、签名后的key以及iv传输至peer2
  2. peer2拿到密文先用base64反序列化,然后通过公钥(可以通过CA也可通过peer获取)用RSA算法解密拿到key,接着用AES-128-CBC反解得到明文。

demo

  • 生成私钥

    openssl genrsa -out rsa_private_key.pem 1024

  • 转成pkcs8格式私钥

    openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt >> rsa_private_key_pkcs8.pem

  • 生成公钥

    openssl rsa -in rsa_private_key_pkcs8.pem -pubout -out rsa_public_key.pem

  • node(8.0LTS)

    const crypto = require(‘crypto’)
    const fs = require(‘fs’)
    // aesKey
    const aesKey = ‘abcdefghijklmnop’
    // iv
    const iv = ‘0000000000000000’
    // privateKey
    const privateKey = fs.readFileSync(‘rsa_private_key_pkcs8.pem’).toString()
    // publicKey
    const publicKey = fs.readFileSync(‘rsa_public_key.pem’).toString()
    // 创建加密类实例
    const cipheriv = crypto.createCipheriv(‘aes-128-cbc’, aesKey, iv)
    // 结果数据结构
    let res = {
    encryptedData: ‘’,
    publicKey,
    encryptedKey: ‘’,
    iv
    }

    // aes加密过程
    let promiseHandler = null
    let cryptoPromise = new Promise((resolve, reject) => {
    promiseHandler = resolve
    })
    cipheriv.on(‘readable’, () => {
    const data = cipheriv.read()
    if (data) res.encryptedData += data.toString(‘hex’)
    })

    cipheriv.on(‘end’, () => {
    res.encryptedData = res.encryptedData
    console.log(aes加密后的密文为:${res.encryptedData})
    promiseHandler()
    })

    cipheriv.write(‘狼牙月,伊人憔悴。忍字诀,几番轮回。’)
    cipheriv.end()

    // 验证公私钥对是否匹配
    const sign = crypto.createSign(‘SHA256’)

    sign.write(aesKey)
    sign.end()
    let signed = sign.sign(privateKey, ‘base64’)
    const verify = crypto.createVerify(‘SHA256’)

    verify.write(aesKey)
    verify.end()

    console.log(aesKey签名结果为:${signed})
    console.log(公私钥是否匹配:${verify.verify(res.publicKey, signed, 'base64')})

    // 数字签名
    res.encryptedKey = crypto.privateEncrypt(privateKey, Buffer.from(aesKey, ‘utf8’)).toString(‘base64’)
    console.log(私钥加密为:${res.encryptedKey})
    // 公钥解密
    let decryptedKey = crypto.publicDecrypt(res.publicKey, Buffer.from(res.encryptedKey, ‘base64’))
    console.log(公钥解密为:${decryptedKey})

    // 利用key和iv去解密res.encryptedData
    let deCipheriv = crypto.createDecipheriv(‘aes-128-cbc’, decryptedKey, res.iv)
    let decrypted = ‘’
    deCipheriv.on(‘readable’, () => {
    const data = deCipheriv.read()
    if (data) decrypted += data.toString(‘utf8’)
    })
    deCipheriv.on(‘end’, () => {
    console.log(aes解密后的明文为:${decrypted})
    })

    cryptoPromise.then(() => {
    deCipheriv.write(res.encryptedData, ‘hex’)
    deCipheriv.end()
    })

what

什么是CSP。CSP(Content-Security-Policy)是一个附加的安全层,用于避免和缓解某些类型的攻击,包括XSS和注入等。CSP向后兼容,浏览器不支持会ignore,默认对网页执行标准的同源策略。可在网站中增加CSP头部,此外根据CSP的标准特点,可通过标签来配置。

includes

  • 源列表(定义源的有效性)

可通过配置以空格为分隔符的有效的目标主机地址字符串 如 http://*.qingf.me blog.qingf.me https://blog.qingf.me

  • 关键字 (定义资源的可访问性)

'none' 代表空集:即不匹配任何URL 'self' 代表文档同源,包括相同的URL协议和端口号。 'unsafe-inline' 允许使用内联资源,如内联的<script>javascript:URL、内联事件处理函数和内联<style> 'unsafe-eval' 允许使用eval()等通过字符串创建代码的方法

Content-Security-Policy: default-src 'self';img-src 'self' data:;

chrome-only

upgrade-insecure-requests 强制网页内http以https发送请求 最低版本为chrome43

<meta name="Content-Security-Policy" content="upgrade-insecure-requests"/>

htmlspecialchars($imgUrl); 把预定义的字符 “<” (小于)和 “>” (大于)转换为 HTML 实体 return string str_replace(“&”, “&”, $imgUrl); 字符串替换 return string preg_replace(“/\?[\s\S]*/“, “”, $imgUrl); 字符串正则替换 return string $pathRes = parse_url($imgUrl); 解析url。 return array_object 例:http://www.baidu.com?query=1#/hash/a 结果:$pathRes[‘scheme’]; // http strpos($ImgUrl, “http”) 获取字符串2在字符串1中的位置 return number $heads = get_headers($imgUrl, 1); 获取当前url服务器响应的请求头 return array_object stristr($heads[0], “200”); 查找 “world” 在 “Hello world!” 中的第一次出现 return 字符串的剩余部分 $sites = [“Runoob”, “Google”] in_array(“Runoob”, $sites) return Boolean


下载网络文件方法

$context = stream_context_create(); return 资源流上下文 readfile($imgUrl,false,$context) 从$context流中读取文件到缓冲区 $img = ob_get_contents(); 此函数返回输出缓冲区的内容,且_不会_主动清空缓冲区,亦或是如果输出缓冲区无效将返回FALSE ob_end_clean(); 清空缓冲区


file_exists(); 函数检查文件或目录是否存在。 return Boolean mkdir($path, mode = 0777, recursive = true) 创建目录(此处须确保php有write权限)

导火线 2017-10-28日飞猪上线“在线签证中心”,试图实现各国签证刘晨在线话,“一机一本”看世界。本事皆大欢喜的事,结果爆出涉嫌抄袭,报着吃瓜群众看大佬操作的心态去搜索相关文章。 然而 熊猫签证创始人:熊猫签证是首款提供线上办签证全套流程的工具APP。飞猪新上线的“在线签证中心”以及这些一模一样的功能,我们早在2016年就已经完美实现。 我想大家多少已经感觉到其中的不可告人 无论如何,阿里飞猪,你这只飞在风口的猪,吃相真是难看。 阿里爸爸,这是你第几次盗窃了? 这不禁让我想起前段时间有所耳闻的丑事 在今天这个故事里,阿里巴巴就是四十大盗 今天才知道,我们在阿里的遭遇不是个例,是不是真有四十大盗呢?

公司企业文化再积极,也难以避免被龌龊无耻小人钻空子。我依然坚信阿里是一家值得信赖的企业,希望不要被几颗老鼠屎坏了一锅粥!

what? Artificial Intelligence。AI聊天机器人核心模块NLP。 why? 携手无人驾驶、VR、AR等等热门词汇并肩引领世界技术潮流 how? 基于规则(rule-based)和基于模型(model-based)

  • 什么是信息熵?

  • 是香农为量化信息价值含量的概念。并得出一个计算公式。可简单理解为信息在传输过程中损耗的价值,信息熵越大,信息的价值越低

  • 什么是模型?

  • 可以理解为一个公式y=f(x)。

  • 模型的分类?

    1. 分类模型(意图识别),输入用户的一句话,吐出一个标签,这个标签就是这句话的意图(intent)
    2. seq2seq判别模型(实体提取),从上面这句话中提取实体(entity)。 ex: 比如,我要一张从北京到上海的机票 分类模型会输出“购买机票”的意图 seq2seq判别模型会抽取“北京”为出发地,“上海”为目的地
  • 如何获取模型?

    1. 模型是基于数据,经由训练得到的。
  • 什么是数据?怎么获取训练集?如何评估训练集的质量?

  • 什么是训练?如何训练?