Swift字符串转换为ASCII四字符代码FourCharCode
Swift字符串转换为ASCII四字符代码FourCharCode

Swift字符串转换为ASCII四字符代码FourCharCode

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” 就是一个标识符,一眼就知道它和“截图”有关。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注