Blog

二进制中1的个数

Content #

考察下面表达式的效果:

n & (n - 1)

以n=1100为例,n-1的结果为1011,相当于把最右边的1变成0,而该位右边的0全部变成1。于是上面的表达式的结果相当于将最右边的1转换成0。

int count = 0
while (n) {
  count++;
  n &= (n-1);
}
return count;

From #

https://leetcode-cn.com/problems/number-of-1-bits/

cook:ffprobe&ffplay

Content #

  1. 查看多媒体数据包信息

    ffprobe -show_packets input.flv
    
  2. 查看媒体数据包的具体数据

    ffprobe -show_data -show_packets input.flv
    
  3. 用json或flat格式查看流信息

    ffprobe -of json -show_packets input.flv
    ffprobe -of flat -show_packets input.flv
    
  4. 使用show_streams过滤帧信息音频(a),视频(v),字幕(s)

    ffprobe -show_frames -select_streams v -of xml input.mp4
    
  5. 强制从第30秒开始,播放10秒

    ffplay -ss 30 -t 10 input.mp4
    
  6. 指定视频流编号为4,音频流编号为5

    ffplay -vst 4 -ast 5 input.ts
    
  7. 展现音频数据的音频波形

    ffplay -showmode 1 input.mp3
    
  8. 显示宏块信息

    ffplay -debug vis_mb_type -ss 20 -t 10 -autoexit input.mp4
    
  9. 查看B帧预测与P帧预测信息

    ffplay -vismv pf input.mp4 #vismv可能会过时
    ffplay -flags2 +export_mvs -ss 40 input.mp4 -vs codecview=mv=pf+bf+bb #滤镜
    
  10. 查询视频文件的duration

    ...

更改封装与编码的实例(rmvb to mp4)

Content #

通过设置AVCodec与AVFormat的操作参数进行封装与编码的改变:

ffmpeg -i ~/Movies/input1.rmvb -vcodec mpeg4 -b:v 200k -r 15 -an output.mp4

● 转封装格式从RMVB格式转换为MP4格式● 视频编码从RV40转换为MPEG4格式● 视频码率从原来的377kbit/s转换为200kbit/s ● 视频帧率从原来的23.98fps转换为15fps ● 转码后的文件中不包括音频(-an参数)首先解封装,需要解的封装为RMVB;然后解码,其中视频编码为RV40,音频编码为COOK;然后解码后的视频编码为MPEG4;最后封装为一个没有音频的MP4文件。

From #

FFmpeg从入门到精通

lgdt

Content #

lgdt指令从指定的内存地址处加载6字节的数据到寄存器GDTR。在这6字节的内存区域中,要求前(低)16位是GDT的界限值,后(高)32位是GDT的基地址。

该指令在实模式和保护模式下都可以执行,但是在实模式下使用16位的有效地址 m访问内存;在32位保护模式下使用32位的有效地址m访问内存。

该指令不影响任何标志位。

From #

setup_paging(head.s)

Content #

//代码路径:boot/head.s

.align 2
setup_paging:
    movl   $1024*5,%ecx           /* 5 pages - pg_dir + 4 page tables */
    xorl   %eax,%eax
    xorl   %edi,%edi              /* pg_dir is at 0x000 */
    cld;rep;stosl
/*下面几行中的7应看成二进制的111,是页属性,代表u/s、r/w、present,
111代表:用户u、读写rw、存在p,000代表:内核s、只读r、不存在  */
    movl   $pg0 + 7,_pg_dir       /* set present bit/user r/w */
    movl   $pg1 + 7,_pg_dir + 4   /*  --------- " " --------- */
    movl   $pg2 + 7,_pg_dir + 8   /*  --------- " " --------- */
    movl   $pg3 + 7,_pg_dir + 12  /*  --------- " " --------- */
    movl   $pg3 + 4092,%edi
    movl   $0xfff007,%eax         /*  16Mb -4096 + 7 (r/w user,p) */
    std
1: stosl                          /* fill pages backwards-more efficient :-) */
    subl   $0x1000,%eax
    jge 1b
    

这些工作完成后,内存中的布局如 内存结构图(head.s执行后)所示。可以看出,只有184字节的剩余代码。

...

混合加密(TLS)

Content #

在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题。

然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。

对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。

这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性。

Viewpoints #

From #

24 | 固若金汤的根本(上):对称加密与非对称加密

ECC(Elliptic Curve Cryptography)

Content #

ECC(Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。

目前比较常用的两个曲线是 P-256(secp256r1,在 OpenSSL 称为 prime256v1)和 x25519。P-256 是 NIST(美国国家标准技术研究所)和 NSA(美国国家安全局)推荐使用的曲线,而 x25519 被认为是最安全、最快速的曲线。

ECC 名字里的“椭圆”经常会引起误解,其实它的曲线并不是椭圆形,只是因为方程很类似计算椭圆周长的公式,实际的形状更像抛物线,比如下面的图就展示了两个简单的椭圆曲线。

两个简单的椭圆曲线:y^2=x^3+7,y^2=x^3-x

比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。

Viewpoints #

From #

24 | 固若金汤的根本(上):对称加密与非对称加密

加密分组模式

Content #

对称算法还有一个“分组模式”的概念,它可以让算法用固定长度的密钥加密任意长度的明文,把小秘密(即密钥)转化为大秘密(即密文)。

最早有 ECB、CBC、CFB、OFB 等几种分组模式,但都陆续被发现有安全漏洞,所以现在基本都不怎么用了。最新的分组模式被称为 AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305。

把上面这些组合起来,就可以得到 TLS 密码套件中定义的对称加密算法。

比如,AES128-GCM,意思是密钥长度为 128 位的 AES 算法,使用的分组模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 算法,使用的分组模式是 Poly1305。

Viewpoints #

From #

24 | 固若金汤的根本(上):对称加密与非对称加密

TLS加密套件命名规则

Content #

浏览器和服务器在使用 TLS 建立连接时需要选择一组恰当的加密算法来实现安全通信,这些算法的组合被称为“密码套件”(cipher suite,也叫加密套件)。

客户端和服务器都支持非常多的密码套件,而最后协商选定的是“ECDHE-RSA-AES256-GCM-SHA384”。

TLS 的密码套件命名非常规范,格式固定。基本的形式是“密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法”

比如刚才的密码套件的意思就是:

“握手时使用 ECDHE 算法进行密钥交换,用 RSA 签名和身份认证,握手后的通信使用 AES 对称算法,密钥长度 256 位,分组模式是 GCM,摘要算法 SHA384 用于消息认证和产生随机数。”

Viewpoints #

From #

23 | HTTPS是什么?SSL/TLS又是什么?

通信安全四特性

Content #

如果通信过程具备了四个特性,就可以认为是“安全”的。

  1. 机密性(Secrecy/Confidentiality)

指对数据的“保密”,只能由可信的人访问,对其他人是不可见的“秘密”,简单来说就是不能让不相关的人看到不该看的东西。

比如小明和小红私下聊天,但“隔墙有耳”,被小强在旁边的房间里全偷听到了,这就是没有机密性。

  1. 完整性(Integrity,也叫一致性)

指数据在传输过程中没有被篡改,不多也不少,“完完整整”地保持着原状。

机密性虽然可以让数据成为“秘密”,但不能防止黑客对数据的修改,黑客可以替换数据,调整数据的顺序,或者增加、删除部分数据,破坏通信过程。

比如,小明给小红写了张纸条:“明天公园见”。小强把“公园”划掉,模仿小明的笔迹把这句话改成了“明天广场见”。小红收到后无法验证完整性,信以为真,第二天的约会就告吹了。

  1. 身份认证(Authentication)

指确认对方的真实身份,也就是“证明你真的是你”,保证消息只能发送给可信的人。

如果通信时另一方是假冒的网站,那么数据再保密也没有用,黑客完全可以使用冒充的身份“套”出各种信息,加密和没加密一样。

比如,小明给小红写了封情书:“我喜欢你”,但不留心发给了小强。小强将错就错,假冒小红回复了一个“白日做梦”,小明不知道这其实是小强的话,误以为是小红的,后果可想而知。

  1. 不可否认(Non-repudiation/Undeniable)

也叫不可抵赖,意思是不能否认已经发生过的行为,不能“说话不算数”“耍赖皮”。

使用前三个特性,可以解决安全通信的大部分问题,但如果缺了不可否认,那通信的事务真实性就得不到保证,有可能出现“老赖”。

比如,小明借了小红一千元,没写借条,第二天矢口否认,小红也确实拿不出借钱的证据,只能认倒霉。另一种情况是小明借钱后还了小红,但没写收条,小红于是不承认小明还钱的事,说根本没还,要小明再掏出一千元。

Viewpoints #

From #

23 | HTTPS是什么?SSL/TLS又是什么?