我有一个非常长的字符串(600多个字符),持有一个大的十进制值(是的,我知道 - 听起来像一个BigInteger),需要这个值的字节表示。
有没有简单的方法可以使用swift存档?
static func decimalStringToUInt8Array(decimalString:String) -> [UInt8] {
...
}
答案 0 :(得分:2)
我写了一个函数来转换你的数字字符串。这是用Swift 1.2编写的。
func decimalStringToUInt8Array(decimalString:String) -> [UInt8] {
// Convert input string into array of Int digits
let digits = Array(decimalString).map{String($0).toInt()!}
let numdigits = digits.count
// Array to hold the result, in reverse order
var bytes:[UInt8] = []
// Convert array of digits into array of Int values each
// representing 6 digits of the original number. Six digits
// was chosen to work on 32-bit and 64-bit systems.
// Compute length of first number. It will be less than 6 if
// there aren't a multiple of 6 digits in the number.
var ints:[Int] = Array(count: (numdigits + 5)/6, repeatedValue: 0)
var rem = numdigits % 6
if rem == 0 {
rem = 6
}
var index = 0
var accum = 0
for digit in digits {
accum = accum * 10 + digit
if --rem == 0 {
rem = 6
ints[index++] = accum
accum = 0
}
}
// Repeatedly divide value by 256, accumulating the remainders.
// Repeat until original number is zero
while ints.count > 0 {
var carry = 0
for (index, value) in enumerate(ints) {
var total = carry * 1000000 + value
carry = total % 256
total /= 256
ints[index] = total
}
bytes.append(UInt8(truncatingBitPattern: carry))
// Remove leading Ints that have become zero.
while ints.count > 0 && ints[0] == 0 {
ints.removeAtIndex(0)
}
}
// Reverse the array and return it
return reverse(bytes)
}
println(decimalStringToUInt8Array("0")) // prints "[0]"
println(decimalStringToUInt8Array("255")) // prints "[255]"
println(decimalStringToUInt8Array("256")) // prints "[1,0]"
println(decimalStringToUInt8Array("1024")) // prints "[4,0]"
println(decimalStringToUInt8Array("16777216")) // prints "[1,0,0,0]"
这是反向功能。你会发现它非常相似:
func uInt8ArrayToDecimalString(uint8array:[UInt8]) -> String {
// For efficiency in calculation, combine 3 bytes into one Int.
let numvalues = uint8array.count
var ints:[Int] = Array(count: (numvalues + 2)/3, repeatedValue: 0)
var rem = numvalues % 3
if rem == 0 {
rem = 3
}
var index = 0
var accum = 0
for value in uint8array {
accum = accum * 256 + Int(value)
if --rem == 0 {
rem = 3
ints[index++] = accum
accum = 0
}
}
// Array to hold the result, in reverse order
var digits:[Int] = []
// Repeatedly divide value by 10, accumulating the remainders.
// Repeat until original number is zero
while ints.count > 0 {
var carry = 0
for (index, value) in enumerate(ints) {
var total = carry * 256 * 256 * 256 + value
carry = total % 10
total /= 10
ints[index] = total
}
digits.append(carry)
// Remove leading Ints that have become zero.
while ints.count > 0 && ints[0] == 0 {
ints.removeAtIndex(0)
}
}
// Reverse the digits array, convert them to String, and join them
return join("", digits.reverse().map{String($0)})
}
进行往返测试以确保我们回到我们开始的地方:
let a = "1234567890987654321333555777999888666444222000111"
let b = decimalStringToUInt8Array(a)
let c = uInt8ArrayToDecimalString(b)
if a == c {
println("success")
} else {
println("failure")
}
结果:“成功”
答案 1 :(得分:1)
您可以使用NSData(int: Int, size: Int)
方法获取Int到NSData,然后从NSData获取字节到数组:[UInt8]
。
一旦你知道这一点,唯一的办法是知道阵列的大小。 Darwin在pow
函数中派上用场。这是一个有效的例子:
func stringToUInt8(string: String) -> [UInt8] {
if let int = string.toInt() {
let power: Float = 1.0 / 16
let size = Int(floor(powf(Float(int), power)) + 1)
let data = NSData(bytes: &int, length: size)
var b = [UInt8](count: size, repeatedValue: 0)
return data.getBytes(&b, length: size)
}
}
答案 2 :(得分:0)
你总是可以这样做:
let bytes = [UInt8](decimalString.utf8)
如果你想要UTF-8字节。
答案 3 :(得分:0)
如果您在十进制字符串上实现了除法,则可以重复除以256。提示第一个分区是你最不重要的字节。
这是一个用C中的标量除法的例子(假设数字的长度存储在A [0]中并将结果写入同一个数组中):
void div(int A[], int B)
{
int i, t = 0;
for (i = A[0]; i > 0; i--, t %= B)
A[i] = (t = t * 10 + A[i]) / B;
for (; A[0] > 1 && !A[A[0]]; A[0]--);
}