Строка равна нулю при обратном преобразовании из NSData

Я пытаюсь зашифровать шестнадцатеричную строку с помощью библиотеки C, героический подвиг, соединяющий Swift, Objective-C и C.

Однако конечным результатом, когда я конвертирую свой NSData в String, является nil.

Я начинаю с этого:

let fakeHex = "9F1D53E732E48F25F94711D5B22086778278624F715D9B2BEC8FB81134E7C904".toData()
let data = Data(repeating: 1, count: 32)

data представляет собой набор из 32 значений true

fakeHex — это жестко запрограммированное шестнадцатеричное число, которое я запускаю через следующее расширение для кодирования UTF8:

extension String {

    func toData() -> Data {
        let data = NSMutableData()
        let terminator = [0]
        for char in self {
            let encodedString = String(char).data(using: .utf8)!
            data.append(encodedString)
            data.append(terminator, length: 1)
        }

        return Data(referencing: data)
    }

}

Затем у меня есть класс Objective-C с именем Blakey, который берет шестнадцатеричный код NSData и trues NSData и хэширует их через Blake2. алгоритм хеширования:

let x = Blakey().createKeyPair(withHexData: fakeHex, andIndexData: data) 

^ это также возвращает некоторые NSData

- (NSData *)createKeyPairWithHexData:(NSData *)data andIndexData:(NSData *)indexData;
{
    struct blake2b_state__ state;
    blake2b_init(&state, 32);

    blake2b_update(&state, data.bytes, data.length); // data.length is 128
    blake2b_update(&state, indexData.bytes, indexData.length); // indexData.length is 32

    void *foo = malloc(32);
    blake2b_final(&state, foo, 32);

    NSData *accountKey = [NSData dataWithBytes:foo length:32];

    free(foo);

    return accountKey;
}

Этот код смоделирован на основе того, что происходит в сопутствующей реализации на Python:

def seed_account(seed, index):
    # (seed here is our hex string, index is 1)
    # Given an account seed and index #, provide the account private and public keys
    h = blake2b(digest_size=32)

    seed_data = BitArray(hex=seed)
    seed_index = BitArray(int=index,length=32)

    h.update(seed_data.bytes)
    h.update(seed_index.bytes)

    return account_key = BitArray(h.digest())

Наконец, я беру NSData из функции Blakey и пытаюсь преобразовать его в строку:

NSString(data: x!, encoding: String.Encoding.utf8.rawValue)
String(data: x!, encoding: .utf8)

Оба печатают nil.

Я делаю что-то не так в процессе, не знаю, что. Хотелось бы помощи, если что-то выделяется.

Спасибо!


person Zack Shapiro    schedule 07.12.2017    source источник
comment
На самом деле расширение кодирует строку utf16. Вы можете сделать то же самое с "9F1D5...C904".data(using: .utf16)!. Однако встроенные решения добавляют спецификацию FFFE   -  person vadian    schedule 07.12.2017
comment
Я понимаю, что могу это сделать, но откуда вы берёте utf16? Мой код let encodedString = String(char).data(using: .utf8)!   -  person Zack Shapiro    schedule 07.12.2017
comment
Интересно, что изменение на utf16 возвращает китайский и японский языки, а не ноль Optional("냨ひ箹刚頶苩Ǜ䭋止ᒊ䙩꾩㓋龘")   -  person Zack Shapiro    schedule 07.12.2017
comment
Простой вопрос: должно ли x вообще представлять строку?   -  person Larme    schedule 07.12.2017
comment
Ваше расширение toData() преобразует каждый символ в utf8 и добавляет нулевой байт, что практически аналогично преобразованию в utf16 для данной строки.   -  person vadian    schedule 07.12.2017
comment
@вадиан Спасибо. Я предполагаю, что хочу кодировать в utf8, хотя это возвращает мне ноль   -  person Zack Shapiro    schedule 07.12.2017
comment
@Larme Я подумал, что взять строку, разбить ее на данные, зашифровать ее и вернуть данные, а затем преобразовать в строку будет представлять строку, но, возможно, я ошибаюсь. Я предположил, что алгоритм хеширования возьмет B, сделает свое волшебство, вернет 9 или 5 в виде байтов, а затем я смогу преобразовать его данные обратно в строку.   -  person Zack Shapiro    schedule 07.12.2017
comment
@Larme теперь, когда я смотрю на другой код, большая часть его имеет дело с байтами до гораздо более позднего времени, когда он кодирует и выплевывает его обратно после некоторого преобразования, но все же на этом этапе я не должен быть в состоянии преобразовать некоторые данные которая ранее была строкой и была зашифрована обратно в строку, которая выглядит иначе после того, как была зашифрована?   -  person Zack Shapiro    schedule 07.12.2017
comment
Не обязательно. Дело в том, чтобы зашифровать строку (которая имеет смысл как строка). Он преобразует его в данные с помощью некоторого алгоритма. Зашифрованные данные не обязательно должны иметь смысл сами по себе, их нужно расшифровать, чтобы они имели смысл. Вы можете использовать base64EncodedStringWithOptions:, когда это режим данных, чтобы получить строку или, другими словами, сделать ее удобочитаемой для человека, но это всего лишь предположение.   -  person Larme    schedule 07.12.2017
comment
Понял, спасибо. Есть еще несколько шагов, я думаю   -  person Zack Shapiro    schedule 07.12.2017


Ответы (1)


Вы добавляете терминатор после каждого символа, но вы, вероятно, захотите добавить его в конец строки (этот data.append(terminator, length: 1))

person user1232690    schedule 08.12.2017