Преобразовал NSData в Data в Swift, и теперь, когда я пытаюсь преобразовать байты в [UInt], я получаю сбой - PullRequest
0 голосов
/ 25 декабря 2018

Вот старый код Objective C (токен NSData):

const unsigned *tokenBytes = [credentials.token bytes];
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                      ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                      ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                      ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

Вот как я преобразовал его в Swift:

let tokenBytes = credentials.token.withUnsafeBytes { (bytes: UnsafePointer<[UInt]>) -> [UInt] in
        return bytes[0] // Crash here
    }

    let hexToken = String(format: "%08x%08x%08x%08x%08x%08x%08x%08x",
                          UInt(bigEndian: tokenBytes[0]), UInt(bigEndian: tokenBytes[1]),
                          UInt(bigEndian: tokenBytes[2]), UInt(bigEndian: tokenBytes[3]),
                          UInt(bigEndian: tokenBytes[4]), UInt(bigEndian: tokenBytes[5]),
                          UInt(bigEndian: tokenBytes[6]), UInt(bigEndian: tokenBytes[7])
    )

Кто-нибудь знает, что яделать неправильно?Насколько я знаю, я правильно конвертировал из bytes в withUnsafeBytes, но, похоже, я ошибаюсь.

1 Ответ

0 голосов
/ 25 декабря 2018

Причиной сбоя является следующее выражение:

bytes : UnsafePointer<[UInt]>

Предполагается, что данные представляют собой последовательность UInt.Таким образом, указатель на начало данных не так опасен, как указатель на [UInt], массив UInt;это небезопасный указатель на UInt, т. е. первый в ряду.Вы должны сказать:

bytes : UnsafePointer<UInt>

Вот вам и авария.Теперь давайте поговорим о том, что вы в основном пытаетесь сделать здесь.

Я не уверен, что должен делать формат строки, но я понимаю, что идея ntohl состоит в том, чтобы гарантировать порядковый номернекоторые длинные C длиной (32 бита).Поэтому я опущу часть строкового формата и просто расскажу о том, как вы могли бы принять поток C long int, полученный в Data, и обратить вспять порядковый номер long int.

Предположим, d является изменяемым Data(то есть объявлено с var).Затем, предполагая, что это представляет последовательность значений с прямым порядком байтов UInt32, и вы хотите преобразовать их в значения с прямым порядком байтов, вы скажете:

let ct = d.count/4
d.withUnsafeMutableBytes{
    (ptr:UnsafeMutablePointer<UInt32>) in
    for ix in 0..<ct {
        ptr[ix] = ptr[ix].bigEndian
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...