>

UInt8 배열이 있습니다  36의 문자열로 바꿔야합니다. 바이너리 정수에 맞는 것으로 변환해야한다고 생각합니다.

let bArray: [UInt8] = ..... //some array of UInt8
let foo = ? // bArray -> a binary integer ... or another step?
let baseString = String(foo, radix: 36, uppercase: false)

이것이 올바른 과정입니까, 아니면 다른 접근법을 사용해야합니까?

<시간>

샘플 데이터

문자열 "test"  바이트 배열을 얻기 위해 SHA1을 사용하여 해시됩니다.

[169, 74, 143, 229, 204, 177, 155, 166, 28, 76, 8, 115, 211, 145, 233, 135, 152, 47, 187, 211]

기초 36 예상 :

jrwjerxiekdtj9k82lg930wpkr6tq6r

16 진수 :

a94a8fe5ccb19ba61c4c0873d391e987982fbbd3


  • 답변 # 1

    이것은 기본 10에 대해 이미 작성 했으므로 2...36 의 모든 기본 버전은 다음과 같습니다. :

    func bytesToRadix<C: RangeReplaceableCollection>(_ bytes: C, radix: Int, isUppercase: Bool = false, isBigEndian: Bool = true) -> String where C.Element == UInt8 {
        // Nothing to process or radix outside of 2...36, return an empty string.
        guard !bytes.isEmpty, 2...36 ~= radix else { return "" }
        let bytes = isBigEndian ? bytes : C(bytes.reversed())
        // For efficiency in calculation, combine 7 bytes into one Int.
        let chunk = 7
        let numvalues = bytes.count
        var ints = Array(repeating: 0, count: (numvalues + chunk - 1)/chunk)
        var rem = numvalues % chunk == 0 ? chunk : numvalues % chunk
        var index = 0
        var accum = 0
        for value in bytes {
            accum = (accum << 8) + Int(value)
            rem -= 1
            if rem == 0 {
                rem = chunk
                ints[index] = accum
                index += 1
                accum = 0
            }
        }
        // Array to hold the result, in reverse order
        var digits = [Int]()
        // Repeatedly divide value by radix, accumulating the remainders.
        // Repeat until original number is zero
        while !ints.isEmpty {
            var carry = 0
            for (index, value) in ints.enumerated() {
                var total = (carry << (8 * chunk)) + value
                carry = total % radix
                total /= radix
                ints[index] = total
            }
            digits.append(carry)
            // Remove leading Ints that have become zero.
            ints = .init(ints.drop { $0 == 0 })
        }
        // Create mapping of digit Int to String
        let letterOffset = Int(UnicodeScalar(isUppercase ? "A" : "a").value - 10)
        let letters = (0 ..< radix).map { d in d < 10 ? "\(d)" : String(UnicodeScalar(letterOffset + d)!) }
        // Reverse the digits array, convert them to String, and join them
        return digits.reversed().map { letters[$0] }.joined()
    }
    
    

    예 :

    let face: [UInt8] = [0xFA, 0xCE]
    print(bytesToRadix(face, radix: 16))  // "face"
    print(bytesToRadix(face, radix: 16, isUppercase: true))  // "FACE"
    print(bytesToRadix(face, radix: 16, isBigEndian: false))  // "cefa""
    print(bytesToRadix(face, radix: 16, isUppercase: true, isBigEndian: false))  // "CEFA"
    print(bytesToRadix(face, radix: 10)) // "64206"
    print(bytesToRadix(face, radix: 2))  // "111101011001110"
    print(bytesToRadix(face, radix: 36)) // "1dji"
    // also works with Data
    let faceData = Data([0xFA, 0xCE])
    print(bytesToRadix(face, radix: 16))  // "face"
    
    

    일부 사례 :

    print(bytesToRadix([9], radix: 16))   // "9"
    print(bytesToRadix([10], radix: 16))  // "a"
    print(bytesToRadix([15], radix: 16))  // "f"
    print(bytesToRadix([16], radix: 16))  // "10"
    print(bytesToRadix([35], radix: 36))  // "z"
    print(bytesToRadix([36], radix: 36))  // "10"
    
    

    대형 테스트 :

    let bArray = (0...255).map(UInt8.init)
    print(bytesToRadix(bArray, radix: 16, isBigEndian: false))
    
    
    와이즈 비즈

    fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100

    와이즈 비즈 <시간>

    샘플 데이터로 테스트 :

    print(bytesToRadix(bArray, radix: 36))
    
    
    와이즈 비즈

    168swoi6iuzj4fbwknlnh695zl88v65qcfgnwrwepqcxb9dysmluowqahvt3r9gsc1v47ssxdivjda3nttl6r044pzz7zwhtgu2mkow5ts28x2mbwenh3wfz4s1sarspfhlrakvqrgpmzb66sgtz2lzbotl7r28wcq8925c747b44l60vrk3scrin4zvnwn7pdsukgo6lgjhu1nuwj7yt1h9ujpe3os17onsk7sp4ysmytu568do2tqetwnrmbxb2dtd8kqorcoakaizlm9svr8axe1acxfursz11nubrhighfd64yhmp99ucvzr944n8co01o4x64cmbd8be0hqbm2zy5uwe4uplc4sa50xajel4bkkxb1kh21pisna37eqwpbpq11ypr

    와이즈 비즈 <시간>

    역 기능 : let bArray: [UInt8] = [169, 74, 143, 229, 204, 177, 155, 166, 28, 76, 8, 115, 211, 145, 233, 135, 152, 47, 187, 211] print(bytesToRadix(bArray, radix: 16))

    여기서 역 기능의 빠른 버전이 있습니다. 아직 대문자를 사용하거나 엔디안을 처리 할 수 ​​없습니다 (빅 엔디안이 가정 됨).

    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

  • 답변 # 2

    데이터 (바이트)에서 정수로 변환 한 다음 기본 36으로 변환하려고하는 것 같습니다 :

    print(bytesToRadix(bArray, radix: 36))
    
    
    <시간>

    jrwjerxiekdtj9k82lg930wpkr6tq6r

    radixToBytes

관련 자료

  • 이전 javascript - NavBar를 작성하여 조치 수행
  • 다음 c++ - 작업 스케줄러 - runlevel을 설정할 때 액세스가 거부되었습니다