两位数字PIN转Base64编码问题求助(Swift)
问题
我需要实现用户在文本框输入两位数字PIN,将其转换为对应字节后再转Base64编码。例如输入01需输出AQ==,输入02输出Ag==,输入99输出mQ==。有两个疑问:
- 两位数字[0-9][0-9]是否都能生成唯一的Base64值?
- 我的代码无法正常工作:输入“01”时得到MDE=,字节数不符合预期(我需要仅1字节的结果);输入“0”时得到MA==,字节数正确但仅为一位数字。我知道核心逻辑有误,尝试过的编解码方案都让我更困惑,推测问题可能和字符串转Int再转Data有关,但无法直接将Int传入.data方法。以下是我的Swift代码:
.onChange(of: channelKey, perform: { value in // Limit input to two digits because that is what we want let totalBytes = value.utf8.count if totalBytes > 2 { if let maxBytesString = value.truncated(to: 2) { channelKey = maxBytesString } } let base64EncodedString = channelKey.data(using: .utf8)!.base64EncodedString() print("base64EncodedString: ", base64EncodedString) // prints “1” as MQ== })
解答
关于唯一性问题
两位数字的范围是00到99,对应十进制整数0到99,每个整数都能映射到唯一的1字节值(99小于255,在UInt8的有效范围内)。Base64是对二进制数据的可逆编码,每个唯一的字节值必然对应唯一的Base64结果,因此所有两位数字PIN都能生成唯一的Base64值。
代码问题修复
你的核心错误是直接将输入字符串(比如"01")按UTF-8编码为Data,这相当于把字符'0'和'1'的ASCII值(48和49)打包成了2字节的Data,转Base64自然得到MDE=。正确逻辑应该是:把两位数字字符串转为对应整数,再将整数打包成1字节的Data,最后转Base64。
修复后的代码如下:
.onChange(of: channelKey, perform: { value in // 过滤非数字字符并限制为两位 let filteredValue = value.filter { $0.isNumber } let limitedValue = String(filteredValue.prefix(2)) channelKey = limitedValue // 转换为0-99范围内的整数,处理无效输入 guard let pinInt = Int(limitedValue), pinInt >= 0, pinInt <= 99 else { print("Invalid PIN") return } // 将整数转为1字节的Data var byte = UInt8(pinInt) let data = Data(bytes: &byte, count: 1) // 生成目标Base64编码 let base64EncodedString = data.base64EncodedString() print("base64EncodedString: ", base64EncodedString) })
代码说明
- 输入处理:先过滤掉非数字字符,再截取前两位,确保输入是有效的数字内容。
- 整数校验:将字符串转为Int并限制在0-99范围内,避免超出1字节UInt8的取值范围。
- 字节转Data:把整数转为UInt8类型,通过
Data(bytes:count:)生成仅1字节的二进制数据。 - Base64编码:对1字节Data进行编码,即可得到符合预期的结果(如输入"01"得到AQ==,输入"99"得到mQ==)。
内容的提问来源于stack exchange,提问作者nore982
相关产品推荐
相关产品推荐

