⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 passwordutils.cpp

📁 A Model-View-Controller Framework that integrates with the MFC Doc/View architecture.
💻 CPP
字号:
#include "stdafx.h"
#include "PasswordUtils.h"

#include <stdlib.h>

const int       NUM_FILLER_CHARS   = 8;
const CString   s_strFillerChars   = _T("SLWMTQYP");
const CString   s_strPossibleChars = _T("0123456789ABCDEFSLWMTQYP");

// local functions
namespace PasswordUtilsLocals
{
	void MakeLength(int nTargetLen, CString& rString);
	long RandomNumber(int nMin, int nMax);
	bool FindIllegalChars(CString& rStrKey);
	void RemoveFillers(CString& rStrKey);
	int  HexStrToInt(const TCHAR *value);
}

void
SbjCore::PasswordUtils::EncryptDate(
  int     nMonth,   // [in]  month
  int     nDay,     // [in]  day
  int     nYear,    // [in]  year
  int     nType,    // [in]  type of password, defined by calling app
  CString& rStrKey) // [out] resulting password
{
	// Seed the random number generator with system time
	CTime t = CTime::GetCurrentTime();
	UINT nTime = static_cast<UINT>( t.GetTime() );
	srand( nTime );

	//for(int i = 0; i < 100; i ++)
	//{
    //	TRACE(_T("%d\n"), EncryptPasswordLocals::RandomNumber(0, NUM_FILLER_CHARS - 1) );
	//}

	// multiply by 100
	long nBigDay   = nDay * 100;
	long nBigMonth = nMonth * 100;
	long nBigYear  = (nYear - 2000) * 100;

	// Get string versions in hex
	CString strDay;
	strDay.Format(_T("%X"), nBigDay);

	CString strMonth;
	strMonth.Format(_T("%X"), nBigMonth);

	CString strYear;
	strYear.Format(_T("%X"), nBigYear);

	// Pad with filler characters to make it 6 chars long
	PasswordUtilsLocals::MakeLength(6, strDay);
	PasswordUtilsLocals::MakeLength(6, strMonth);
	PasswordUtilsLocals::MakeLength(6, strYear);

	// Now reverse each string and concatenate with dashes
	rStrKey.Format(_T("%s-%s-%s-"), strYear.MakeReverse(), strDay.MakeReverse(), strMonth.MakeReverse());

	// Get a 5 digit random number to use for the "type" section
	long n5dig = PasswordUtilsLocals::RandomNumber(10001, 99990);

	CString strTypeSection;
	strTypeSection.Format(_T("%u"), n5dig);

	CString strTypeVal;
	strTypeVal.Format(_T("%u"), nType);

	// Insert the type value in the 4th position in the type string
	strTypeSection.Insert(3, strTypeVal);

	rStrKey += strTypeSection;
}

// --------------------  DecryptPassword  ---------------------
// Deciphers the password into a date.  nType is retuned as
// the same in passed into CreatePassword.  If the password
// cannot be deciphered, false is returned and all 'out' params
// are left unchanged.
// ------------------------------------------------------------
bool
SbjCore::PasswordUtils::DecryptPassword(
  LPCTSTR pPassword, // [in]  password to decipher
  int&    nMonth,    // [out] month
  int&    nDay,      // [out] day
  int&    nYear,     // [out] year
  int&    nType)     // [out] type, same value passed in to CreatePassword
{
	bool bSuccess = true;

	CString strKey(pPassword);

	// Verify length
	if(strKey.GetLength() != 27)
	{
		bSuccess = false;
	}
	// verify the dashes
	if(bSuccess)
	{
		if( strKey[6] != _TCHAR('-') || strKey[13] != _TCHAR('-') || strKey[20] != _TCHAR('-') )
		{
			bSuccess = false;
		}
	}

	// parse out the four strings
	CString strDay;
	CString strMonth;
	CString strYear;
	CString strType;

	strYear  = strKey.Left(6);
	strDay   = strKey.Mid(7, 6);
	strMonth = strKey.Mid(14, 6);
	strType  = strKey.Mid(21, 6);

	// verify only legal characters exist
	if(bSuccess)
	{
		if( PasswordUtilsLocals::FindIllegalChars(strDay)  ||
			PasswordUtilsLocals::FindIllegalChars(strMonth)||
			PasswordUtilsLocals::FindIllegalChars(strYear) ||
			PasswordUtilsLocals::FindIllegalChars(strType)    )
		{
			bSuccess = false;
		}
	}

	// reverse the strings and remove the filler characters
	if(bSuccess)
	{
		strDay   = strDay.MakeReverse();
		strMonth = strMonth.MakeReverse();
		strYear  = strYear.MakeReverse();

		PasswordUtilsLocals::RemoveFillers(strDay);
		PasswordUtilsLocals::RemoveFillers(strMonth);
		PasswordUtilsLocals::RemoveFillers(strYear);

		// What is left at this point is a hex version of the month, day and year
		// still multiplied by 100.

		// Convert it back to decimal numbers
		_stscanf_s (strDay,_T("%x"), &nDay);
		_stscanf_s (strMonth,_T("%x"), &nMonth);
		_stscanf_s (strYear,_T("%x"), &nYear);

		// Divide it back by 100
		nDay /= 100;
		nMonth /= 100;

		// The year used a 2 digit format, so it gets 2000 added on
		nYear = nYear/100 + 2000;

		// Extract the type from its string
		CString strTypeVal(strType[3]);
		nType = atoi(strTypeVal);
	}

	return bSuccess;
}

void
PasswordUtilsLocals::MakeLength(int nTargetLen, CString& rString)
{
	int nLen = rString.GetLength();
	int nPos = 0;
	while(nLen < nTargetLen)
	{
		int nIndex = PasswordUtilsLocals::RandomNumber(0, NUM_FILLER_CHARS - 1);
		nLen = rString.Insert( nPos, s_strFillerChars.GetAt(nIndex) );
		nPos += 2;
	}
}

long
PasswordUtilsLocals::RandomNumber(int nMin, int nMax)
{
	// Get the random number
	double dRanNum = static_cast<double>( rand() );

	// convert it to a range
	double dRandMax  = static_cast<double>(RAND_MAX) + 1.0;
	double dMaxRange = static_cast<double>(nMax);
	double dMinRange = static_cast<double>(nMin);
	int n = static_cast<int>( dRanNum / dRandMax * (dMaxRange - dMinRange) + dMinRange );

	return n;
}

bool
PasswordUtilsLocals::FindIllegalChars(CString& rStrKey)
{
	bool bInvalid = false;
	int nLen = rStrKey.GetLength();

	for(int i = 0; i < nLen; i ++)
	{
		if( s_strPossibleChars.Find(rStrKey.GetAt(i)) == -1 )
		{
			bInvalid = true;
			break;
		}
	}

	return bInvalid;
}

void
PasswordUtilsLocals::RemoveFillers(CString& rStrKey)
{
	CString strTemp(rStrKey);

	rStrKey.Empty();

	int nLen = strTemp.GetLength();
	for(int i = 0; i < nLen; i ++)
	{
		// If it's not a filler add it into the string
		if( s_strFillerChars.Find(strTemp.GetAt(i)) == -1 )
		{
			rStrKey += strTemp.GetAt(i);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -