Показать сообщение отдельно
  (#2 (permalink)) Старый
Влад Влад вне форума
Специалист
 
Сообщений: 3,884
Сказал(а) спасибо: 1
Поблагодарили 25 раз(а) в 25 сообщениях
Регистрация: 27.06.2002
Адрес: Санкт-Петербург
По умолчанию 05.08.2006, 12:59

Пример реализации:
Код:
void CKeyGenDlg::OnGenerate()
{
    // Генерация кода ключа основана на серийном номере винчестера
    const char szDiskName[] = "C:\\";
    char szVolumeNameBuffer[260];
    DWORD dwVolumeNameSize = sizeof(szVolumeNameBuffer);
    DWORD dwVolumeSerialNumber;
    DWORD dwMaxCompLength;
    DWORD dwFileSystemFlags;
    char szSysNameBuf[260];
    DWORD dwSysNameSize = sizeof(szSysNameBuf);

    VERIFY(GetVolumeInformation(szDiskName, szVolumeNameBuffer, dwVolumeNameSize,
        &dwVolumeSerialNumber, &dwMaxCompLength, &dwFileSystemFlags, szSysNameBuf, dwSysNameSize));

    // я получил серийный номер диска. Теперь надо сгенерировать номера и
    // показать их юзеру :
    m_Serial_1 = GenerateNumber( dwVolumeSerialNumber, 0 );
    UpdateData( FALSE );
}

CString CKeyGenDlg::GenerateNumber( DWORD dwSerial, int index )
{
   // маска из 32 байт
   static const BYTE Mask[32] = {
       0x13, 0x24, 0x5D, 0x09, 0x2E, 0x07, 0x17, 0x25,    // 0..7
       0x1B, 0x0B, 0x3F, 0x16, 0x53, 0x18, 0x5B, 0x1B,    // 8..15
       0x08, 0x37, 0x1F, 0x3E, 0x3A, 0x0C, 0x09, 0x14,    // 16..23
       0x49, 0x13, 0x0A, 0x12, 0x1C, 0x24, 0x5C, 0x40    // 24..31
   };

    CString Result;
    Result.Format( "%08X", dwSerial );

    // не вполне очевидная, но необходимая корректировочка для цифр
    // A..F (0x41..0x46):
    for (int i = 0; i < Result.GetLength(); ++i)
        if (Result[i] > '9') Result.SetAt(i, Result[i]-7);

    CString retStr("");
    BYTE c;

    switch( index )
    {
    case 0 :
        c = (Result[0] - Mask[0x1D] ) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[1] + Mask[0x16]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[2] - Mask[2]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[3] + Mask[0x1B]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[4] - Mask[0]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[5] + Mask[9]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[6] - Mask[0x1E]) & 0x0F;
        retStr += GetSymbol(c);
        c = (Result[7] + Mask[0x15]) & 0x0F;
        retStr += GetSymbol(c);
    break;

    default : retStr = "";
    }
    return retStr;
}

// Метод GetSymbol возвращает очередной символ для регнума
char CKeyGenDlg::GetSymbol(BYTE c)
{
    return (char)(c <= 9 ? c+0x30 : c+0x37);  // 0x0A -> 0x41
}


The difference between theory and practice is that in theory, there is no difference between theory and practice, but in practice, there is.
Ответить с цитированием
Ads