Нужна проверка реальности: мой анализ этой ошибки Blowfish VB6 VB6 правильно?
Вопрос
Недавно у меня было причина сравнить алгоритмы взрыва. Я сравнил результаты от Ди управлениябиблиотека и PHP Mcrypt. Отказ Я не мог заставить их договориться.
Это привело меня на интересную погоню. Согласно с Эта публикация На сайте Брюса Шнеевеера в ранних версиях Blowfish Code был продлен расширения знака, и казалось бы, что код управления DI реализует код дохода до ошибок.
Блоку в отчете об ошибках говорит, частично,
bfinit(char *key,int keybytes)
{
unsigned long data;
...
j=0;
...
data=0;
for(k=0;k<4;k++){
data=(data<<8)|key[j];/* choke*/
j+=1;
if(j==keybytes)
j=0;
}
...
}
Это дрочит всякий раз, когда наиболее значительный бит ключа [J] - это «1». Например, если ключ [j] = 0x80, клавиша [j], подписанный символ, представляет собой знак, расширенный на 0xFFFFFFFF80, прежде чем он будет или с помощью данных.
Эквивалентный код в blf_Initialise
Функция в basblowfish.bas
wData = &H0
For k = 0 To 3
wData = uw_ShiftLeftBy8(wData) Or aKey(j)
j = j + 1
If j >= nKeyBytes Then j = 0
Отчет о ошибках предлагает следующее исправление коду C:
data<<=8;
data|=(unsigned long)key[j]&0xff;
который я реализовал в VB6 как
wData = uw_ShiftLeftBy8(wData)
wData = wData Or ( aKey(j) And &HFF )
На самом деле, я написал это, чтобы оба метода используются, а затем вставьте в утверждение, чтобы проверить, являются ли значения одинаковыми или нет, VIZ:
wData = uw_ShiftLeftBy8(wData)
wData = wData Or (aKey(j) And &HFF)
wDCheck = uw_ShiftLeftBy8(wData) Or aKey(j)
Debug.Assert wData = wDCheck
Когда AKey (J) содержит 255, я получаю ошибку утверждения.
Я читаю эту ситуацию Arright? Произошла ли ошибка расширения знака или я вижу ошибки, которые там нет?
Странно, тесты, которые поставляются с кодом управления DI, кажется, правильно работают как с этим, так и без этого изменения (что может означать, что мой поиск эквивалентности между двумя алгоритмами может зависеть от чего-то другого.)
Решение
Если я читаю это правильно (конечно, не гарантированно в этот час), у вас есть ошибка. Может даже два. Помните, что в C типа Chasts имеют более высокий прецедентство, чем побитовые операции. Код C отличает подписанный символ в долгосрочную группу, прежде чем и в нее с 0xFF. Написано добросовестно:
data = (data << 8) | ( ((unsigned long)key[j]) & 0xFF );
Однако код VB, который вы разместили, эквивалентно:
wData = (wData << 8) | (unsigned long)(aKey[j] & 0xFF);
Здравствуйте, расширение знака.
Кроме того, ты хотел написать это?
wDCheck = uw_ShiftLeftBy8(wDCheck) Or aKey(j)
В противном случае вы устанавливаете WDCheck с помощью нового значения WDATA.