macOS 很多老API(Carbon、QuickTime)使用4个ASCII字符来表示一个ID。
本质上是一个UInt32,需要将4个ASCII字符拼到一个32位整数里。
每个ASCII字符由8位二进制数组成,A的二进制数表示为0100 0001,四个ASCII字符的二进制数为32位,因此刚好拼到一个 32 位整数里。
例如,”SHOT” :
S 的 ASCII 码 = 0x53 (十进制 83)
H 的 ASCII 码 = 0x48 (72)
O 的 ASCII 码 = 0x4F (79)
T 的 ASCII 码 = 0x54 (84)
“SHOT”组合的ASCII码为0x53484F54。
同理”TEST”组合的ASCII码为0x54455354。
例如在注册全局快捷键RegisterEventHotKey时,EventHotKeyID 需要一个 signature(来区分不同来源的热键),这里的EventHotKeyID就需要ASCII四字符代码。
实现方案
1、MacRoman版本
extension String {
var fourCharCodeValue: FourCharCode {
precondition(self.utf8.count == 4, "必须正好 4 个 ASCII 字符")
var result: FourCharCode = 0
if let data = self.data(using: .MacOSRoman) {
for (i, byte) in data.enumerated() {
result += FourCharCode(byte) << ((3 - i) * 8)
}
}
return result
}
}
用 MacRoman 编码,将 String 转换为 bytes,返回四个ASCII字符。
以SHOT为例,使用enumerated方法,遍历索引和ASCII字符:
第一个字符S的索引为0,将第一个字符转换为FourCharCode(UInt32的别名)格式,并向左偏移24位。

第二个字符H的索引为1,将第二个字符转换为FourCharCode格式,并向左偏移16位。

第三个字符O的索引为2,将第三个字符转换为FourCharCode格式,并向左偏移8位。

第四个字符T的索引为3,将第四个字符转换为FourCharCode格式,不偏移。

然后手动拼成一个 32 位整数。

这个写法适配性较好(历史遗留,保证和 Carbon 的编码一致)。
注意:enumerated()没有限制长度,如果字符串长度超过4(索引超过3),(3 – i)就会出现负数的情况, 这时的偏移不合法,因此需要检查字符串长度是否为4。
2、UTF-8版本
extension String {
var fourCharCodeValue: UInt32 {
var result: UInt32 = 0
for character in self.utf8.prefix(4) {
result = (result << 8) + UInt32(character)
}
return result
}
}
直接取前 4 个 UTF-8 字节拼成 UInt32。
简单直观,但如果字符串不是纯 ASCII(比如 “你好”),结果就不可预期。
3、简洁版本
extension String {
var fourCharCode: FourCharCode {
precondition(self.count == 4, "必须是4字符")
return self.utf8.reduce(0) { ($0 << 8) | UInt32($1) }
}
}
总结
通过扩展String,可以实现字符串转换为ASCII四字符代码。
let code1 = "SHOT".fourCharCodeValue // 第一种: 0x53484F54
let code2 = "SHOT".fourCharCodeValue // 第二种: 0x53484F54
在实际项目中,第二种(UTF-8)写法最常见,只要保证使用A-Z字符串就不会出问题。
FourCharCode 和 UInt32是等价的:
public typealias FourCharCode = UInt32
相关文章
1、macOS注册全局快捷键RegisterEventHotKey:https://fangjunyu.com/2025/07/26/macos%e6%b3%a8%e5%86%8c%e5%85%a8%e5%b1%80%e5%bf%ab%e6%8d%b7%e9%94%aeregistereventhotkey/
2、ASCII 与 Unicode: 计算机语言的进化史:https://fangjunyu.com/2025/08/21/ascii-%e4%b8%8e-unicode-%e8%ae%a1%e7%ae%97%e6%9c%ba%e8%af%ad%e8%a8%80%e7%9a%84%e8%bf%9b%e5%8c%96%e5%8f%b2/
扩展知识
什么是FourCharCode?
FourCharCode(四字符代码)本质上是一个 32 位无符号整数 (UInt32),用来存放恰好 4 个 ASCII 字符。
每个字符占 1 个字节(8 位)。
4 个字符 × 8 位 = 32 位,正好装进一个 UInt32。
它常被用来作为系统中的标识符,让代码更容易记忆和阅读。
举例,字符串“TEST”:
T 0x54,最高位(左移 24 位)
E 0x45,次高位(左移 16 位)
S 0x53,次低位(左移 8 位)
T 0x54,最低位(直接放入)
组合后就是:
0x54 45 53 54
= 0x54455354
所以:
"TEST" → FourCharCode = 0x54455354
"SHOT" → FourCharCode = 0x53484F54
为什么要用 FourCharCode?
主要是历史原因 + 可读性:
在 QuickTime、Carbon API、音视频格式、系统事件里,很多地方需要一个数字来代表某个类型、事件或资源。
如果直接用数字(例如 123456789),不直观也难记忆。
如果用 “TEST” 这种四字符,看起来更容易懂。
例如在全局快捷键注册里:
EventHotKeyID(signature: "SHOT".fourCharCode, id: 1)
这里 “SHOT” 就是一个标识符,一眼就知道它和“截图”有关。