PDA

Просмотр полной версии : Биты и байты в C++ B.


Yazzer
14.05.2009, 18:58
Помогите вот с такой задачей в C++ B.

есть Ansi строка из 7-ми символов. То есть 7 байт.
Надо сделать её длинной в 8 байт, вставив в исходную строку нулевой бит через каждые 7 бит.

SmanxX1
14.05.2009, 19:44
А в чем проблема то? И зачем это нужно, если не секрет?

Yazzer
14.05.2009, 19:54
В том что я не понимаю как это сделать ))) Плохо понимаю как! )

А надо это для создания двух ключей для DES в алгоритме LM-хеширования.

slesh
14.05.2009, 20:08
нулевой бит? Насколько я помню в DES этот бит нужен для того чтобы проверить точность ключа. т.е. этот бит ставится 1 когда кол-во 1-х битов нечетное и ставится =0 когда кол-во четное. (что не помню примерно так)
А вообще подобная вешь делается сдвигом на асме проще это делать.

Ra$cal
14.05.2009, 20:11
// берешь исходный бит
int src_bit = src_char & 0x01;
// вставить нулевой бит
src_char <<= 1;

ну а дальше по обстоятельствам. можешь собирать перемещенные биты в новый чар
new_char |= src_char & 0x01;
new_char <<= 1;

Yazzer
14.05.2009, 20:16
slesh
Я же пока только ключ делаю для DES шифрования. А для того что бы его сделать, мне надо из 7 байт сделать 8. как раз используя этот нулевой символ.

Надеюсь я вообще правильно понял алгоритм LM - хеша.

Yazzer
14.05.2009, 20:19
// берешь исходный бит
int src_bit = src_char & 0x01;
// вставить нулевой бит
src_char <<= 1;

ну а дальше по обстоятельствам. можешь собирать перемещенные биты в новый чар
new_char |= src_char & 0x01;
new_char <<= 1;



У меня Ansi строка 7 байт, как выбрать первые 7 бит, что бы туда вставить нулевой бит? И потом следующие 7 бит найти..

Yazzer
14.05.2009, 20:21
И вот дополнительный вопрос который меня мучает.. Как потом из AnsiString с этим битовыми выражениями сделать ключ для DES типа "unsigned long"?

Ra$cal
14.05.2009, 20:26
анси строка по сути своей можно привести к char*, т.е. к обычному массиву байтов. сначала получи массив символов. дальше с каждым байтом работаешь как с элементом массива. или я чего то не понимаю в условии?

slesh
14.05.2009, 20:29
а вообще добирайся до битов через сишный возможности ти


typedef struct _KEY
{
char b1:1;
char b2:2;
char b3:3;
char b4:4;
char b5:5;
char b6:6;
char b7:7;
char b8:8;
} TKEY,*PKEY;


int main(int argc, char* argv[])
{
PKEY keybit;
char data[8];
data[0]=127;
keybit=(PKEY)&data[0];
keybit->b1=1; // вот так вот ты можешь добраться до битов
return 0;
}

Yazzer
14.05.2009, 20:36
я сделал вот так.
AnsiString __fastcall StrToDesKey(const AnsiString S)
{
AnsiString key;
key.SetLength(8);
char *dest=key.c_str();
char *src=S.c_str();
dest[0]=src[0] & 0x7F;
int k = 1;
for (int i=1; i < 8; i++; k++)
dest[i]=((src[i-1] >> (8-k)) | (src[i] << k)) & 0x7F;
return key;
}
а посмотрев код DES, то обнаружил что можно использовать и ANSI ключи.

HCRYPTPROV hCryptProv;
DWORD dwUserNameLen = 100;
LPCSTR UserName= NULL;
HCRYPTKEY hKey=DesKey1;
BYTE data[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
BYTE key[8] = {0x13, 0x34, 0x57, 0x79, 0x9B, 0xBC, 0xDF, 0xF1};
BYTE IV[8] = {0, 0, 0, 0, 0, 0, 0, 0};
CryptAcquireContext(&hCryptProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0);
BYTE bKey[20];
DWORD keyLen = 8;
DWORD dataLen = 8;

BLOBHEADER keyHeader;
keyHeader.bType = PLAINTEXTKEYBLOB;
keyHeader.bVersion = CUR_BLOB_VERSION;
keyHeader.reserved = 0;
keyHeader.aiKeyAlg = CALG_DES;
//move keyHeader into buffer
for(i=0; i<sizeof(keyHeader); i++){
bKey[i] = *((BYTE*) &keyHeader + i);
}
//move keySize into buffer
for(i=0; i<sizeof(keyLen); i++){
bKey[i + sizeof(keyHeader)] = *((BYTE*) &keyLen + i);
}
//move key bytes into buffer
for(i=0; i<8; i++){
bKey[i + sizeof(keyHeader) + sizeof(keyLen)] = key[i];
}
//Import key BLOB
CryptImportKey(hCryptProv, (BYTE*) &bKey, sizeof(keyHeader) + sizeof(DWORD) + 8, 0, 0, &hKey);
//set DES mode
DWORD desMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hKey, KP_MODE, (BYTE*) &desMode, 0);
//set padding mode
DWORD padding = ZERO_PADDING;
CryptSetKeyParam(hKey, KP_MODE, (BYTE*) &desMode, 0);
//set iv
CryptSetKeyParam(hKey, KP_IV, &IV[0], 0);
//Set FALSE to avoid padding
CryptEncrypt(hKey, 0, FALSE, 0, (BYTE*) &data[0], &dataLen, 8);
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);

Только теперь у меня вообще ламерский вопрос )) мне надо использовать шифрование строки "KGS!@#$" на ключе
BYTE *key1=(BYTE*)skey1.c_str();
и
BYTE *key2=(BYTE*)skey1.c_str();

Не могу понять, что там в этом DES коде лишнее..

xismyname
15.05.2009, 12:54
а вообще добирайся до битов через сишный возможности ти


typedef struct _KEY
{
char b1:1;
char b2:2;
char b3:3;
char b4:4;
char b5:5;
char b6:6;
char b7:7;
char b8:8;
} TKEY,*PKEY;


int main(int argc, char* argv[])
{
PKEY keybit;
char data[8];
data[0]=127;
keybit=(PKEY)&data[0];
keybit->b1=1; // вот так вот ты можешь добраться до битов
return 0;
}




typedef struct _KEY
{
char b1:1;
char b2:2;
char b3:3;
char b4:4;
char b5:5;
char b6:6;
char b7:7;
char b8:8;
} TKEY,*PKEY;


Выходит что b1 имеет 1 бит,b2 2 биты, b3 3 биты ..... b8 8 битов а всего 36 битов а должно быть всего лишь 8 битов, т.е. :
typedef struct _KEY {
char b1 : 1;
char b2 : 1;
char b3 : 1;
char b4 : 1;
char b5 : 1;
char b6 : 1;
char b7 : 1;
char b8 : 1;
} TKEY,*PKEY;