Для однобайтовых входов алгоритм:
f x = 0x80 .|. (0xF0 .&. x `shiftL` 4) .|. x `xor` 0x05
или в стиле C:
#define F(x) (0x80 | (0xF0 & (x << 4)) | (x ^ 0x05))
РЕДАКТИРОВАТЬ: я изменил 0xF
в 0xF0
, которыйчто я имею в виду.
Соответствует приведенным примерам (необходимо больше примеров).
Вам недостаточно двухбайтовых примеров (см. мой комментарий), поэтому я не буду беспокоиться о них.
РЕДАКТИРОВАТЬ: Как я с этим справился:
Шаг первый: запишите все в битах, пробел разделяйте отрывки (4 бита), потому что дизайны часто делают что-то другое награница клева - то есть они могут x & 0x80 | x ^ 0x05
, но реже x & 0x84 | x ^ 0x01
.
0000 0000 --> 1000 0101
0000 0001 --> 1000 0100
Видите, похоже, что мы получаем 0x80 бесплатно (или), а второй клев получилxor 0x05.Тестирование 0 и 1 было умным.Дистанция Хэмминга, одно значение и нулевые значения всегда хорошие тесты.Итак, сейчас я думаю, что alg:
#define f(x) (x ^ 0x85)
Затем мы получим тестовую пару от 0x85 до 0xd0:
1000 0101 --> 1101 0000
Так что нижний клев по-прежнему выглядит правильно (xor с 0x05) но верхний полубайт должен измениться на ИЛИ, а не на XOR:
#define f(x) ( (0xF0 & x | 0x80) \ // Upper nibble
| 0x0F & (x ^ 0x05)) // Lower nibble
Это то же самое, что и
#define f(x) ( x^0x05 | 0x80)
Но это все еще не делает этого!Обратите внимание, что в нашем результирующем верхнем полубайте мы получаем тот же битовый шаблон, что и во входном нижнем полубайте, видите 0101?Позволяет ИЛИ нижнему клеву с верхним и называть его верхним:
#define f(x) ( (x^0x05) | 0x80 | (0xF0 & (x << 4))
А теперь мы сопоставим все три тестовых случая (что на самом деле немного)
Это нене то, что я изложил выше, что вы приняли, возможно, вы исправили мою опечатку 0xF
в предполагаемом 0xF0
?Если нет, то убедитесь, что вы заметили эту ошибку и изменили свой код.Вы могли бы даже включить несколько модульных тестов с известным ответом, если это для какого-либо серьезного использования.
О, и, так как он у меня под рукой, здесь он в рабочем состоянии.
#include <stdio.h>
#define F(x) (0x80 | (0xF0 & (x << 4)) | (x ^ 0x05))
void main()
{
printf("%02x %02x %02x\n", F(0), F(1), F(0x85));
}