Я использую javascript, и я немного заржавел в своей арифметике.
В конечном счете, моя цель - преобразовать UInt8Array в 11-битные числа для использования со списком слов bip39 для преобразования ключа приватного ящика libsodium в мнемонику (я создаю небольшое приложение для чата p2p-ish).
Итак, мой мыслительный процесс выглядит так:
- Uint8Array возвращается из
libsodium.crypto_box_keypair()
- Преобразование Uint8Array в 256-битный (логический) массив
- разделить 256-битный массив на 11-битные сегменты (2-мерный массив: ~ 24 x 11 бит)
- преобразовать каждый 11-битный массив в базовое число 10 (между 0 и 2047)
Шаги 2, 3и 4 можно объединить в один и тот же цикл.
Цель всего этого - эффективное преобразование массива Uint8Array в массив из 11-битных чисел (эффективно для компьютера - это не былоэффективно для меня).
У меня есть это на данный момент, но это не совсем правильно, и я чувствую себя немного хакерским (только из шагов 2 и 3, где я пытаюсь создать 11-битные сегменты)
// inspired from: https://github.com/pvorb/node-md5/issues/25
export function toUint11Array(input: Uint8Array): boolean[][] {
let result: boolean[][] = [];
let currentChunk: boolean[] = [];
input.forEach(byte => {
for (var j = 7; j >= 0; j--) {
var b = ((byte >> j) & 0x1) > 0;
if (currentChunk.length === 11) {
result.push(currentChunk);
currentChunk = [];
}
currentChunk.push(b);
}
});
return result;
}
В настоящее время для 2048 я получаю 2 11-битных массива(ожидается), но содержимое / порядок неожиданны.
[
false, false, false, false,
false, false, false, false,
false, false, false
],
[ false, true, false, false,
false, false, false, false,
false, false, false
]
2048 - это 0b100_000_000_000
, где 12-я цифра справа - 1 (добавлены подчеркивания для облегчения чтения)
так может, похоже, у меня проблема с порядком байтов и, возможно, одна проблема?потому что истина в моем двойном массиве - 13-я позиция слева.
хотя, когда я тестирую с 4096 (13 бит (0b1_000_000_000_000))), я получаю это:
[
false, false, false, false,
false, false, false, false,
false, false, false
],
[
true, false, false, false,
false, false, false, false,
false, false, false
],
[
false, false, false, false,
false, false, false, false,
false, false, false
]
Здесьtrue
- 12 слева и 22 справа.
Обновление
на @bergi, который спросил о порядке байтов.
Я не знаю, что такое порядок байтовэто.: - \
Обновление 2
Спасибо @harold за то, что пришли с ответом.У меня есть несколько тестов, которые я думаю подтверждает правильность
const numbers = {
['32']: new Uint8Array([32]),
['64']: new Uint8Array([64]),
['2048']: new Uint8Array([8, 0]),
['4096']: new Uint8Array([16, 0]),
['7331']: new Uint8Array([28, 163])
}
test ('toUint11Array | converts | 32 (8 bits)', function(assert) {
const result = toUint11Array(numbers['32']);
const expected = [32];
assert.deepEqual(result, expected);
});
test ('toUint11Array | converts | 2048 (12 bits)', function(assert) {
const result = toUint11Array(numbers['2048']);
const expected = [8, 0];
assert.deepEqual(result, expected);
});
test ('toUint11Array | converts | 4096 (13 bits)', function(assert) {
const result = toUint11Array(numbers['4096']);
const expected = [16, 0];
assert.deepEqual(result, expected);
});
test ('toUint11Array | converts | 7331 (13 bits)', function(assert) {
const result = toUint11Array(numbers['7331']);
const expected = [3, 1187];
assert.deepEqual(result, expected);
});
первые 3 прохода, но последний нет.
при конвертации Uint8Array(28, 163)
, я получаю [796, 28]
Я не на 100%конечно, я правильно преобразовал 7331 в соответствующие байты, но я сделал: 7331 = 0b1_1100_1010_0011
split: [1_1100, 1010_0011]
-> [28, 163]
.
Полагаю, для вывода это должно быть: [11, 100_1010_0011]
, что [3, 1187]
, что также не соответствует выводу.