FourCC
用于标识数据格式,总共四个字节 [1] ,是一个无符号的 32 位整数,每个字节存储一个 ASCII
码,通过串联 4 个ASCII
码来存储
以 1279476545
这个 u32
数字来举例,先转换成二进制
100 1100 0100 0011 0100 0011 0100 0001
取第一个字节,第一个字节在后 8 位数字,这里使用二进制与运算符 &
,让其与 0xff
进行运算,0xff
是一个字节的最大值,这样操作可以保证取出的值在一个字节以内
100 1100 0100 0011 0100 0011 0100 0001
1111 1111
0100 0001
二进制与运算符和 and
运算符一样,如果都为 1 则返回 1,否则为 0
let byte = 1279476545 & 0xff; // 0100 0001
0100 0001
的十进制是 65,对应 UTF8/ASCII
是字母 A
,这样就取出了第一个字节
第二个字节需要用到二进制有符号右移 >>
,右移是将一个二进制操作数对象按指定的位数向右移动,右侧溢出的将会被抛弃,左边的空位用 0 补充。
取第二个字节就需要丢掉 8 个二进制位
100 1100 0100 0011 0100 0011 0100 0001|
xxx xxxx x100 1100 0100 0011 0100 0011|0100 0001
这样 0100 0001
这 8 位就丢掉了,现在再使用 &
取一个字节,并且以此类推,下面是一个 rust
函数的实现
fn fourcc_str(k: u32) -> String {
String::from_utf8(vec![
((k >> 0) & 0xff) as u8,
((k >> 8) & 0xff) as u8,
((k >> 16) & 0xff) as u8,
((k >> 24) & 0xff) as u8,
]).unwrap()
}
assert_eq!(fourcc_str(1279476545), "ACCL");
解析做好了就做合成,以 ACCL
这四个字符为例
先取得它们 ASCII
码的二进制
Char: A C C L
CodeAt: 65 67 67 76
Binary: 0100_0001 0100_0011 0100_0011 0100_1100
再将它们依次存入 32 字节中
0000_0000_0000_0000_0000_0000_{0100_0001} // A
0000_0000_0000_0000_{0100_0011}_0000_0000 // C
0000_0000_{0100_0011}_0000_0000_0000_0000 // C
{0100_1100}_0000_0000_0000_0000_0000_0000 // L
由于它们所在的区域不会重复,因此可以使用二进制或 |
运算符进行合并,结果
0100_1100_0100_0011_0100_0011_0100_0001
下面是一个 rust
函数的实现
fn make_fourcc(a: char, b: char, c: char, d: char) -> u32 {
((a as u32) << 0)
| ((b as u32) << 8)
| ((c as u32) << 16)
| ((d as u32) << 24)
}
assert_eq!(make_fourcc('A', 'C', 'C', 'L'), 1279476545);
-
一个字节存储 8 位无符号整数,最小 00000000,最大 11111111,即 255,一个字节可以存放一个
ASCII
码 ↩