用于数据和标识符的 Base32Crockford 编码的 Swift 包。
ThirtyTo 提供了一种编码数据和创建标识符的方法,既高效又具有可读性。虽然 Base64 更高效,但由于同时包含大小写字母和标点符号,因此可读性不强。
Apple 平台
Linux
使用 Swift Package Manager 通过存储库 URL 安装此库
https://github.com/brightdigit/ThirtyTo.git
使用最高到 1.0
的版本。
在编码数据方面,Base32Crockford 提供了最合理的折衷方案。 作为 Base16 的超集,它使用所有十个数字和 26 个拉丁字母大写字符中的 22 个。
符号值 | 解码符号 | 编码符号 |
---|---|---|
0 | 0 O o | 0 |
1 | 1 I i L l | 1 |
2 | 2 | 2 |
3 | 3 | 3 |
4 | 4 | 4 |
5 | 5 | 5 |
6 | 6 | 6 |
7 | 7 | 7 |
8 | 8 | 8 |
9 | 9 | 9 |
10 | A a | A |
11 | B b | B |
12 | C c | C |
13 | D d | D |
14 | E e | E |
15 | F f | F |
16 | G g | G |
17 | H h | H |
18 | J j | J |
19 | K k | K |
20 | M m | M |
21 | N n | N |
22 | P p | P |
23 | Q q | Q |
24 | R r | R |
25 | S s | S |
26 | T t | T |
27 | V v | V |
28 | W w | W |
29 | X x | X |
30 | Y y | Y |
31 | Z z | Z |
ThirtyTo 能够以 Base32Crockford 编码和解码数据,以及创建唯一标识符。 有多种编码和解码选项可用。
所有编码和解码都通过 Base32CrockfordEncoding.encoding
对象完成。 这提供了编码和解码数据以及标准化的接口。
要编码任何数据,请调用
public func encode(
data: Data,
options: Base32CrockfordEncodingOptions = .none
) -> String
因此,要编码 Data
对象,只需通过以下方式调用
let data : Data // 0x00b003786a8d4aa28411f4e268c43629
let base32String = Base32CrockfordEncoding.encoding.encode(data: data)
print(base32String) // P01QGTMD9AH884FMW9MC8DH9
如果要解码字符串,可以调用 Base32CrockfordEncoding.decode
let data = try Base32CrockfordEncoding.encoding.decode(
base32Encoded: "P01QGTMD9AH884FMW9MC8DH9"
) // 0x00b003786a8d4aa28411f4e268c43629
Base32CrockfordEncoding.encode
对象提供了指定格式选项和校验和的功能。
您可以选择在末尾提供校验和字符,以便尽早且经济地检测传输和输入错误。
根据规范
校验符号编码模 37 的数字,37 是大于 32 的最小素数。我们引入了 5 个额外的符号,这些符号仅用于编码或解码校验符号。
额外的 5 个符号是
符号值 | 解码符号 | 编码符号 |
---|---|---|
32 | * | * |
33 | ~ | ~ |
34 | $ | $ |
35 | = | = |
36 | U u | U |
如果要包含校验和,请为 Base32CrockfordEncodingOptions
对象上的 withChecksum
属性传递 true
let data : Data // 0xb63d798c4329401684d1d41d3becc95c
let base32String = Base32CrockfordEncoding.encoding.encode(
data: data,
options: .init(withChecksum: true)
)
print(base32String) // 5P7NWRRGS980B89MEM3MXYSJAW5
解码带有校验和的字符串时,必须为 Base32CrockfordDecodingOptions
上的 withChecksum
属性指定 true
let data = try Base32CrockfordEncoding.encoding.decode(
base32Encoded: "5P7NWRRGS980B89MEM3MXYSJAW5"a,
options: .init(withChecksum: true)
) // 0xb63d798c4329401684d1d41d3becc95c
除了添加校验和之外,Base32CrockfordEncodingOptions
还提供了添加分组分隔符的功能。
根据 Base32Crockford 规范
连字符 (-) 可以插入到符号字符串中。 这可以将字符串划分为可管理的部分,通过帮助防止混淆来提高可读性。 解码期间将忽略连字符。
要将连字符插入到编码字符串中,请将 GroupingOptions
对象提供给 Base32CrockfordEncodingOptions
let data : Data // 00c9c37484b85a42e8b3e7fbf806f2661b
let base32StringGroupedBy3 = Base32CrockfordEncoding.encoding.encode(
data: data,
options: .init(groupingBy: .init(maxLength: 3))
)
let base32StringGroupedBy9 = Base32CrockfordEncoding.encoding.encode(
data: data,
options: .init(groupingBy: .init(maxLength: 9))
)
print(base32StringGroupedBy3) // 69R-DT8-9E2-T8B-MB7-SZV-Z03-F4S-GV2
print(base32StringGroupedBy9) // 69RDT89E2-T8BMB7SZV-Z03F4SGV2
解码时,将忽略连字符
let dataNoHyphens = try Base32CrockfordEncoding.encoding.decode(
base32Encoded: "69RDT89E2T8BMB7SZVZ03F4SGV2"
) // 00c9c37484b85a42e8b3e7fbf806f2661b
let dataGroupedBy3 = try Base32CrockfordEncoding.encoding.decode(
base32Encoded: "69R-DT8-9E2-T8B-MB7-SZV-Z03-F4S-GV2"
) // 00c9c37484b85a42e8b3e7fbf806f2661b
let dataGroupedBy9 = try Base32CrockfordEncoding.encoding.decode(
base32Encoded: "69RDT89E2-T8BMB7SZV-Z03F4SGV2"
) // 00c9c37484b85a42e8b3e7fbf806f2661b
assert(dataNoHyphens == dataGroupedBy3) // true
assert(dataNoHyphens == dataGroupedBy9) // true
assert(dataGroupedBy3 == dataGroupedBy9) // true
ThirtyTo 提供了在通用工厂中创建不同类型标识符的功能。 虽然开发人员可以使用 UUID
,但此库提供了一个接口来创建其他两种类型。 为此,您可以调用 IdentifierFactory/createIdentifier(with:)
在 Identifier/factory
上创建提供的三种类型中的任何一种
UUID
- 标准通用标识符ULID
- 通用唯一可排序标识符UDID
- 动态大小的随机标识符每种类型都有相应的 ComposableIdentifier/Specifications
UUID
不需要任何规范,可以使用 IdentifierFactory.createIdentifier(_:)
创建ULID
采用 ULID/Specifications
UDID
采用 AnyIdentifierSpecifications
这是一个 UDID
的示例
// create an identifier for 1 million unique IDs that is a factor of 5.
let specs = AnyIdentifierSpecifications(
size: .minimumCount(1_000_000, factorOf: 5)
)
let identifier: UDID = Identifier.factory.createIdentifier(with: specs)
ULID
的目的是解决 UUID
的几个问题,同时保持兼容性
最重要的是,它使用 Base32Crockford 以获得更好的效率和可读性。
要创建 ULID,您可以使用 IdentifierFactory.createIdentifier(with:)
在 Identifier.factory
上
let ulid : ULID = Identifier.factory.createIdentifier(with: .parts(nil, .random(nil)))
或构造函数
let ulid = ULID(specifications: .parts(nil, .random(nil)))
在大多数情况下,默认的 ULID.Specifications.default
规范就足够了。 这遵循规范规范,该规范使用前 6 个字节作为时间戳,最后 10 个字节是随机的。 否则,您可以使用 ULID.Specifications.data(_:)
指定所有 16 个字节,或者指定用于时间戳的 Date
和用于数据的 ULID.randomPart
的 RandomDataGenerator
。
此代码在 MIT 许可下分发。 有关更多信息,请参见 LICENSE 文件。