08 June 2008

MD5, SHA-1, uuencode… in VC++, eVC++ and PHP

MD5, SHA-1やuuencodeを行うサンプル
(端末でハッシュを計算し、サーバに送信してハッシュ値を再確認する時などに使えるでしょう…)

Visual C++ または eMbedded Visual C++ のとき


void メイン関数()
{
// TODO : ここにコントロール通知ハンドラ コードを追加します。

char sData[1024];
// TCHAR wsData[1024]; // eVC++(Windows CE)のとき、ダイアログから文字列を得るのは wchar *
char sEncodedData[2048];
BYTE pcbData[32];
CString sHash;
CString sTemp;
int i;

GetDlgItemText(IDC_EDIT_STR, sData, 1023); // 元の文字列をダイアログのテキストボックスから得る

// eVC++(Windows CE)の場合
// GetDlgItemText(IDC_EDIT_STR, wsData, 1023);
// ::wcstombs(sData, wsData, 1023);


// MD5計算
CalcHash(sData, (DWORD)strlen(sData), pcbData, 16, CALG_MD5);

sHash = "";
for(i = 0; i < 16; i++)
{
sTemp.Format(_T("%x"),pcbData[i]);
sHash += sTemp;
}

SetDlgItemText(IDC_EDIT_MD5, sHash); // テキストボックスに計算結果をセットする

// SHA-1計算
CalcHash(sData, (DWORD)strlen(sData), pcbData, 20, CALG_SHA1);

sHash = "";
for(i = 0; i < 20; i++)
{
sTemp.Format(_T("%x"),pcbData[i]);
sHash += sTemp;
}

SetDlgItemText(IDC_EDIT_SHA1, sHash);

//Base64変換
::ZeroMemory(sEncodedData, sizeof(sEncodedData));
i = sizeof(sEncodedData);
Base64Encode((const BYTE*)sData, (int)strlen(sData), sEncodedData, &i);

SetDlgItemText(IDC_EDIT_BASE64, sEncodedData);

//uuencode変換
::ZeroMemory(sEncodedData, sizeof(sEncodedData));
i = sizeof(sEncodedData);
UUEncode((const BYTE*)sData, (int)strlen(sData), sEncodedData, &i);

SetDlgItemText(IDC_EDIT_UUENCODE, sEncodedData);
}

bool CalcHash(const void * pData, DWORD dwDataLen, BYTE *pcbHashData, DWORD dwHashLen, DWORD dwFlag)
{
bool ret;
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
BYTE pbHash[0x7f];

::ZeroMemory(pcbHashData, dwHashLen);
if(pData == NULL || dwDataLen == 0)
return false;

hHash = NULL;
hCryptProv = NULL;
ret = false;
if(::CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
{
if(::CryptCreateHash(hCryptProv,dwFlag,0,0,&hHash))
{
if(::CryptHashData(hHash,(BYTE*)pData,dwDataLen,0))
{
if(::CryptGetHashParam(hHash,HP_HASHVAL,pbHash,&dwHashLen,0))
{
::memcpy(pcbHashData,pbHash,dwHashLen);
ret = true;
}
}
}
}

if(hHash)
::CryptDestroyHash(hHash);
if(hCryptProv)
::CryptReleaseContext(hCryptProv,0);

if(ret == false)
::ZeroMemory(pcbHashData,dwHashLen);

return ret;
}


PHPのとき


<p>ハッシュ値の計算</p>

<p>
<form action = "hash.php" method = "post" >
<input type="text" name="plain_str">
<input type="submit" name="POST_SEND" value="ハッシュ値計算">
</form>
</p>

<?php

if($_POST["plain_str"])
{
$sPlain = $_POST["plain_str"];
$arrVer = explode(".", phpversion()); // 例えば、「4.4.8」 を 分解

print('<p>元の文字列:'.htmlspecialchars($sPlain).'</p>');

print('<p>MD5:'.MD5($sPlain).'</p>');

print('<p>SHA1:'.sha1($sPlain).'</p>');

if($arrVer[0] >= 5)
{ // PHP5以上でのみサポートされる関数
print('<p>uuencode:'.htmlspecialchars(convert_uuencode($sPlain)).'</p>');
print('<p>uuencode (decode):'.htmlspecialchars(convert_uudecode($sPlain)).'</p>');
}

print('<p>base64:'.htmlspecialchars(base64_encode($sPlain)).'</p>');
print('<p>base64 (decode):'.htmlspecialchars(base64_decode($sPlain)).'</p>');

print('<p>urlencode:'.htmlspecialchars(urlencode($sPlain)).'</p>');
print('<p>urldecode:'.htmlspecialchars(urldecode($sPlain)).'</p>');

print('<p>bin2hex:'.htmlspecialchars(bin2hex($sPlain)).'</p>');

print('<hr><p>php version='.phpversion());
}
?>