Esempio n. 1
0
UniqueID::UniqueID()
{
	time_t m_time;
	int m_pid;
	char userName[255];
	char hostName[255];
	int ip = 3434;



	time(&(m_time));
	UniqueID::basedata += m_time;
	

	m_pid = _getpid();

	strcpy(userName,getenv(ENVSTRING));


	WSADATA wsaData;

	if(WSAStartup(MAKEWORD( 2, 2),&wsaData) == 0)
	{
		gethostname(hostName,255);	

		HOSTENT * host = gethostbyname(hostName);
		memcpy((void*)&ip, host->h_addr, 4);
	}
	else
	{
		strcpy(hostName,"ERROR_SOCKET");
	}

#ifdef WIN32
	MEMORYSTATUS lpBuffer;   // memory status structure
	GlobalMemoryStatus(&lpBuffer);
	int paso = (lpBuffer.dwAvailVirtual >> 8) * GenRandom() + GenRandom();	
#else
	int paso = GenRandom() * GenRandom();
#endif WIN32


	char* temp = uid;
	sprintf(temp,"%04.4x-",m_pid);
	temp += 5;
	sprintf(temp,"%08.8x-",m_time);
	temp += 9;	
	sprintf(temp,"%08.8x",do_hash(userName) + ip);
	temp += 8;
	sprintf(temp,"%08.8x-",do_hash(hostName) + ip);
	temp += 9;
	sprintf(temp,"%08.8x",paso);

	UniqueID::basedata++;
}
Esempio n. 2
0
std::string InspIRCd::GenRandomStr(int length, bool printable)
{
	char* buf = new char[length];
	GenRandom(buf, length);
	std::string rv;
	rv.resize(length);
	for(int i=0; i < length; i++)
		rv[i] = printable ? 0x3F + (buf[i] & 0x3F) : buf[i];
	delete[] buf;
	return rv;
}
Esempio n. 3
0
std::string GenRandomString( int len )
{

    const int lCharSetsize = strlen(RandStrCharSet);

    std::string lRet(len,' ');
    for(int i = 0; i<len; ++i)
    {
        int lseed = GenRandom();
        lRet[i] = RandStrCharSet[lseed%lCharSetsize];
    }
    return lRet;

}
Esempio n. 4
0
// NOTE: this has a slight bias for lower values if max is not a power of 2.
// Don't use it if that matters.
unsigned long InspIRCd::GenRandomInt(unsigned long max)
{
	unsigned long rv;
	GenRandom((char*)&rv, sizeof(rv));
	return rv % max;
}
Esempio n. 5
0
/*
    ==========================================================================
    Description:
        Timer execution function for periodically updating group key.
    Return:
    ==========================================================================
*/
VOID GREKEYPeriodicExec(
    IN PVOID SystemSpecific1,
    IN PVOID FunctionContext,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3)
{
	UINT i, apidx;
	ULONG temp_counter = 0;
	struct rtmp_adapter *pAd = (struct rtmp_adapter *)FunctionContext;
	PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3;
	MULTISSID_STRUCT *pMbss = NULL;
	struct rtmp_wifi_dev *wdev;

	for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
	{
		if (&pAd->ApCfg.MBSSID[apidx].REKEYTimer == pTimer)
			break;
	}

	if (apidx == pAd->ApCfg.BssidNum)
		return;
	else
		pMbss = &pAd->ApCfg.MBSSID[apidx];

	wdev = &pMbss->wdev;
	if (wdev->AuthMode < Ndis802_11AuthModeWPA ||
		wdev->AuthMode > Ndis802_11AuthModeWPA1PSKWPA2PSK)
		return;

    if ((pMbss->WPAREKEY.ReKeyMethod == TIME_REKEY) && (pMbss->REKEYCOUNTER < 0xffffffff))
        temp_counter = (++pMbss->REKEYCOUNTER);
    /* REKEYCOUNTER is incremented every MCAST packets transmitted, */
    /* But the unit of Rekeyinterval is 1K packets */
    else if (pMbss->WPAREKEY.ReKeyMethod == PKT_REKEY)
        temp_counter = pMbss->REKEYCOUNTER/1000;
    else
    {
		return;
    }

	if (temp_counter > (pMbss->WPAREKEY.ReKeyInterval))
    {
        pMbss->REKEYCOUNTER = 0;
		pMbss->RekeyCountDown = 3;
        DBGPRINT(RT_DEBUG_TRACE, ("Rekey Interval Excess, GKeyDoneStations=%d\n", pMbss->StaCount));

        /* take turn updating different groupkey index, */
		if ((pMbss->StaCount) > 0)
        {
			/* change key index */
			wdev->DefaultKeyId = (wdev->DefaultKeyId == 1) ? 2 : 1;

			/* Generate GNonce randomly */
			GenRandom(pAd, wdev->bssid, pMbss->GNonce);

			/* Update GTK */
			WpaDeriveGTK(pMbss->GMK,
						(u8 *)pMbss->GNonce,
						wdev->bssid, pMbss->GTK, LEN_TKIP_GTK);

			/* Process 2-way handshaking */
            for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
            {
				MAC_TABLE_ENTRY  *pEntry;

				pEntry = &pAd->MacTab.Content[i];
				if (IS_ENTRY_CLIENT(pEntry) &&
					(pEntry->WpaState == AS_PTKINITDONE) &&
						(pEntry->apidx == apidx))
                {
					pEntry->GTKState = REKEY_NEGOTIATING;

#ifdef DROP_MASK_SUPPORT
					/* Disable Drop Mask */
					set_drop_mask_per_client(pAd, pEntry, 1, 0);
					set_drop_mask_per_client(pAd, pEntry, 2, 0);
#endif /* DROP_MASK_SUPPORT */

                	WPAStart2WayGroupHS(pAd, pEntry);
                    DBGPRINT(RT_DEBUG_TRACE, ("Rekey interval excess, Update Group Key for  %x %x %x  %x %x %x , DefaultKeyId= %x \n",\
										PRINT_MAC(pEntry->Addr), wdev->DefaultKeyId));
				}
			}
		}
	}

	/* Use countdown to ensure the 2-way handshaking had completed */
	if (pMbss->RekeyCountDown > 0)
	{
		pMbss->RekeyCountDown--;
		if (pMbss->RekeyCountDown == 0)
		{
			unsigned short Wcid;

			/* Get a specific WCID to record this MBSS key attribute */
			GET_GroupKey_WCID(pAd, Wcid, apidx);

			/* Install shared key table */
			WPAInstallSharedKey(pAd,
								wdev->GroupKeyWepStatus,
								apidx,
								wdev->DefaultKeyId,
								Wcid,
								true,
								pMbss->GTK,
								LEN_TKIP_GTK);
		}
	}

}
Esempio n. 6
0
/*
    ==========================================================================
    Description:
        Function to handle countermeasures active attack.  Init 60-sec timer if necessary.
    Return:
    ==========================================================================
*/
VOID HandleCounterMeasure(struct rtmp_adapter *pAd, MAC_TABLE_ENTRY *pEntry)
{
	INT         i;
	bool     Cancelled;

	if (!pEntry)
		return;

	/* Todo by AlbertY - Not support currently in ApClient-link */
	if (IS_ENTRY_APCLI(pEntry))
		return;

	/* if entry not set key done, ignore this RX MIC ERROR */
	if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED))
		return;

	DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n"));

	/* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */
	pEntry->CMTimerRunning = true;
	pAd->ApCfg.MICFailureCounter++;

	/* send wireless event - for MIC error */
	RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0);

	if (pAd->ApCfg.CMTimerRunning == true) {
		DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n"));

		/* send wireless event - for counter measures */
		RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0);
		ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M);

		/* renew GTK */
		GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce);

		/* Cancel CounterMeasure Timer */
		RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled);
		pAd->ApCfg.CMTimerRunning = false;

		for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
			/* happened twice within 60 sec,  AP SENDS disaccociate all associated STAs.  All STA's transition to State 2 */
			if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) {
				MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, false);
			}
		}

		/*
			Further,  ban all Class 3 DATA transportation for a period 0f 60 sec
			disallow new association , too
		*/
		pAd->ApCfg.BANClass3Data = true;

	/* check how many entry left...  should be zero */
	/*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */
	/*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */
	}

	RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE);
	pAd->ApCfg.CMTimerRunning = true;
	pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime;
	RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime);
}
/*
==========================================================================
	Description:
	    
	IRQL = PASSIVE_LEVEL
==========================================================================
*/
VOID
TDLS_BuildSetupRequest(
	IN	PRTMP_ADAPTER	pAd,
	OUT PUCHAR	pFrameBuf,
	OUT PULONG	pFrameLen,
	IN	PRT_802_11_TDLS	pTDLS)
{
	ULONG			Timeout = TDLS_TIMEOUT;
	BOOLEAN			TimerCancelled;
	/* fill action code */
	TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_SETUP_REQUEST);

	/* fill Dialog Token */
	pAd->StaCfg.TdlsDialogToken++;
	if (pAd->StaCfg.TdlsDialogToken == 0)
		pAd->StaCfg.TdlsDialogToken++;

	pTDLS->Token = pAd->StaCfg.TdlsDialogToken;
	TDLS_InsertDialogToken(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->Token);

	/* fill link identifier */
	TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pAd->CurrentAddress, pTDLS->MacAddr);

	// fill capability
	TDLS_InsertCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// fill ssid
	TDLS_InsertSSIDIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// fill support rate
	TDLS_InsertSupportRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// fill ext rate
	TDLS_InsertExtRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// fill Qos Capability
	TDLS_InsertQosCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

#ifdef DOT11_N_SUPPORT
	// fill HT Capability
	TDLS_InsertHtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// fill 20/40 BSS Coexistence (7.3.2.61)
#ifdef DOT11N_DRAFT3
	TDLS_InsertBSSCoexistenceIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);
#endif // DOT11N_DRAFT3 //
#endif // DOT11_N_SUPPORT //

	// fill  Extended Capabilities (7.3.2.27)
	TDLS_InsertExtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

	// TPK Handshake if RSNA Enabled
	// Pack TPK Message 1 here! 
	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
		((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)))
	{		
		UCHAR			CipherTmp[64] = {0};
		UCHAR			CipherTmpLen = 0;
		FT_FTIE			FtIe;
		ULONG			KeyLifetime = TDLS_KEY_TIMEOUT;	// sec
		ULONG			tmp;
		UCHAR			Length;
		
		// RSNIE (7.3.2.25)
		CipherTmpLen = CipherSuiteTDLSLen;	
		if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
			NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskTkip, CipherTmpLen);
		else
			NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskAes, CipherTmpLen);
		
		// update AKM
		if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
			CipherTmp[19] = TDLS_AKM_SUITE_1X;
		
		// Insert RSN_IE to outgoing frame
		MakeOutgoingFrame((pFrameBuf + *pFrameLen),	&tmp,
				CipherTmpLen,						&CipherTmp,
				END_OF_ARGS);

		*pFrameLen = *pFrameLen + tmp;
	
			
		// FTIE (7.3.2.48)
		NdisZeroMemory(&FtIe, sizeof(FtIe));
		Length =  sizeof(FtIe);

		// generate SNonce
		GenRandom(pAd, pAd->CurrentAddress, FtIe.SNonce);
		hex_dump("TDLS - Generate SNonce ", FtIe.SNonce, 32);
		NdisMoveMemory(pTDLS->SNonce, FtIe.SNonce, 32);
		
		TDLS_InsertFTIE(
				pAd, 
				(pFrameBuf + *pFrameLen), 
				pFrameLen, 
				Length, 
				FtIe.MICCtr,
				FtIe.MIC, 
				FtIe.ANonce, 
				FtIe.SNonce);

		
		// Timeout Interval (7.3.2.49)
		TDLS_InsertTimeoutIntervalIE(
				pAd, 
				(pFrameBuf + *pFrameLen), 
				pFrameLen, 
				2, /* key lifetime interval */
				KeyLifetime);

		pTDLS->KeyLifetime = KeyLifetime;

	}

	// ==>> Set sendout timer
	RTMPCancelTimer(&pTDLS->Timer, &TimerCancelled);
	RTMPSetTimer(&pTDLS->Timer, Timeout);
	// ==>> State Change

	pTDLS->Status = TDLS_MODE_WAIT_RESPONSE;

}
/*
==========================================================================
	Description:
	    
	IRQL = PASSIVE_LEVEL
==========================================================================
*/
VOID
TDLS_BuildSetupResponse(
	IN	PRTMP_ADAPTER	pAd,
	OUT PUCHAR	pFrameBuf,
	OUT PULONG	pFrameLen,
	IN	PRT_802_11_TDLS	pTDLS,
	IN	UCHAR	RsnLen,
	IN	PUCHAR	pRsnIe,
	IN	UCHAR	FTLen,
	IN	PUCHAR	pFTIe,
	IN	UCHAR	TILen,
	IN	PUCHAR	pTIIe,
	IN	UINT16	StatusCode)
{
	/* fill action code */
	TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_SETUP_RESPONSE);

	/* fill status code */
	TDLS_InsertStatusCode(pAd, (pFrameBuf + *pFrameLen), pFrameLen, StatusCode);

	/* fill Dialog Token */
	TDLS_InsertDialogToken(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->Token);

	if (StatusCode == MLME_SUCCESS)
	{
		/* fill link identifier */
		TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->MacAddr, pAd->CurrentAddress);

		// fill capability
		TDLS_InsertCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

		// fill ssid
		TDLS_InsertSSIDIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

		// fill support rate
		TDLS_InsertSupportRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

		// fill ext rate
		TDLS_InsertExtRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

		// fill Qos Capability
		TDLS_InsertQosCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);

#ifdef DOT11_N_SUPPORT
		// fill HT Capability
		TDLS_InsertHtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen);
#endif // DOT11_N_SUPPORT //

		// TPK Handshake if RSNA Enabled
		// Pack TPK Message 2 here! 
		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
			((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)))
		{		
			FT_FTIE	*ft;
			ULONG	tmp;
			UINT	key_len = LEN_PMK;

			// RSNIE (7.3.2.25)			
			// Insert RSN_IE of the Peer TDLS to outgoing frame
			MakeOutgoingFrame((pFrameBuf + *pFrameLen),	&tmp,
					RsnLen,								pRsnIe,
					END_OF_ARGS);
			*pFrameLen = *pFrameLen + tmp;

			// FTIE (7.3.2.48)
			// Construct FTIE (IE + Length + MIC Control + MIC + ANonce + SNonce)
			
			// point to the element of IE
			ft = (FT_FTIE *)(pFTIe + 2);	
			// generate ANonce
			GenRandom(pAd, pAd->CurrentAddress, ft->ANonce);
			hex_dump("TDLS - Generate ANonce ", ft->ANonce, 32);
			// set MIC field to zero before MIC calculation
			NdisZeroMemory(ft->MIC, 16);
			// copy SNonce from peer TDLS
			NdisMoveMemory(ft->SNonce, pTDLS->SNonce, 32);
			// copy ANonce to TDLS entry
			NdisMoveMemory(pTDLS->ANonce, ft->ANonce, 32);

			//if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
				//key_len = 48;
			// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
			// Derive TPK-KCK for MIC key, TPK-TK for direct link data
			TDLS_FTDeriveTPK(
					pTDLS->MacAddr,	/* MAC Address of Initiator */
					pAd->CurrentAddress, /* I am Responder */
					pTDLS->ANonce, 
					pTDLS->SNonce, 
					pAd->CommonCfg.Bssid,
					key_len,
					pTDLS->TPK,
					pTDLS->TPKName);

			// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

			////////////////////////////////////////////////////////////////////////
			// The MIC field of FTIE shall be calculated on the concatenation, in the following order, of
			// 1. MAC_I (6 bytes)
			// 2. MAC_R (6 bytes)
			// 3. Transaction Sequence = 2 (1 byte)
			// 4. Link Identifier (20 bytes)
			// 5. RSN IE without the IE header (20 bytes)
			// 6. Timeout Interval IE (7 bytes)
			// 7. FTIE without the IE header, with the MIC field of FTIE set to zero (82 bytes)	
			{
				UCHAR	content[512];
				ULONG	c_len = 0;
				ULONG	tmp_len = 0;
				UCHAR	Seq = 2;
				UCHAR	mic[16];
				UCHAR	LinkIdentifier[20];
				UINT	tmp_aes_len = 0;

				NdisZeroMemory(LinkIdentifier, 20);
				LinkIdentifier[0] = IE_TDLS_LINK_IDENTIFIER;
				LinkIdentifier[1] = 18;
				NdisMoveMemory(&LinkIdentifier[2], pAd->CommonCfg.Bssid, 6);
				NdisMoveMemory(&LinkIdentifier[8], pTDLS->MacAddr, 6);
				NdisMoveMemory(&LinkIdentifier[14], pAd->CurrentAddress, 6);

				NdisZeroMemory(mic, sizeof(mic));

				/* make a header frame for calculating MIC. */
				MakeOutgoingFrame(content,					&tmp_len,
			                      MAC_ADDR_LEN,				pTDLS->MacAddr,
			                      MAC_ADDR_LEN,				pAd->CurrentAddress,
			                      1,						&Seq,
			                      END_OF_ARGS);
				c_len += tmp_len;					

				/* concatenate Link Identifier */			
			    MakeOutgoingFrame(content + c_len,		&tmp_len,
			                      20,					LinkIdentifier,
			                      END_OF_ARGS);
				c_len += tmp_len;					

				/* concatenate RSNIE */
			    MakeOutgoingFrame(content + c_len,		&tmp_len,
			                      20,					(pRsnIe + 2),
			                      END_OF_ARGS);
				c_len += tmp_len;					

				/* concatenate Timeout Interval IE */
				MakeOutgoingFrame(content + c_len,     &tmp_len,
								  7,					pTIIe,
								  END_OF_ARGS);
				c_len += tmp_len;

				/* concatenate FTIE */			
			    MakeOutgoingFrame(content + c_len,		&tmp_len,
			                      sizeof(FT_FTIE),	(PUCHAR)ft,
			                      END_OF_ARGS);
				c_len += tmp_len;

				/* Calculate MIC */				
				//AES_128_CMAC(pTDLS->TPK, content, c_len, mic);

				/* Compute AES-128-CMAC over the concatenation */
				tmp_aes_len = AES_KEY128_LENGTH;
    			AES_CMAC(content, c_len, pTDLS->TPK, 16, mic, &tmp_aes_len);

				// Fill Mic to ft struct
				NdisMoveMemory(ft->MIC, mic, 16);

			}
			////////////////////////////////////////////////////////////////////////
			
			// Insert FT_IE to outgoing frame
			TDLS_InsertFTIE(
					pAd, 
					(pFrameBuf + *pFrameLen), 
					pFrameLen, 
					sizeof(FT_FTIE), 
					ft->MICCtr, 
					ft->MIC, 
					ft->ANonce, 
					ft->SNonce);

			// Timeout Interval (7.3.2.49)
			// Insert TI_IE to outgoing frame
			TDLS_InsertTimeoutIntervalIE(
					pAd, 
					(pFrameBuf + *pFrameLen), 
					pFrameLen, 
					2, /* key lifetime interval */
					pTDLS->KeyLifetime);
		}	
	}
}
Esempio n. 9
0
	void GenUniRandVec(uint32_t uStart, uint32_t uEnd, uint32_t uNum, vector<uint32_t>& randVec)
	{
		uint32_t uOrignSize = uEnd - uStart + 1;
		if (uNum > uOrignSize + 1 || uNum == 0)					// 超过能随机的范围, 或者不需要随机
		{
			return;
		}

		/*
			如果需要不重复的随机数和数据源的比列比较接近,那么采用数组下标置换算法
			如果需要不重复的随机数占数据源的比列比较少,那么采用随机碰撞算法
			如果数据源本身数据在100以内,并且随机比列低于0.2,那么直接只用数组下标置换算法
		*/

		// 随机碰撞方式
		if ((uOrignSize > 100 && uOrignSize * 0.3 >= uNum) || (uOrignSize <= 100 && uOrignSize * 0.2 >= uNum))
		{
			do 
			{
				uint32_t uRandIndex = GenRandom(uStart, uEnd);

				// 查找是否已经存在了
				bool bFind = false;
				vector<uint32_t>::iterator randIt = randVec.begin();
				vector<uint32_t>::iterator randItEnd = randVec.end();
				for (; randIt != randItEnd; randIt++)
				{
					if (uRandIndex == *randIt)
					{
						bFind = true;
					}
				}

				if (!bFind)
				{
					randVec.push_back(uRandIndex);
				}

			} while (randVec.size() < uNum);
			
			return;
		}

		// 采用数组下标置换算法,需要先复制一次数据
		vector<uint32_t> tmpVec;
		for (uint32_t uRank=uStart; uRank<=uEnd; uRank++)
		{
			tmpVec.push_back(uRank);
		}
		/*
			采用数组下标置换的方式,传入的orignVec需要是指定随机范围内数字排序好之后的数组
			如果获得了指定数量的随机值后,算法就终止
		*/
		uint32_t uRandCount = 0;
		for (uint32_t i=0; i<uOrignSize; i++)
		{
			if (uRandCount == uNum)
			{
				break;
			}

			// 在min和max之间随机一个数字
			uint32_t uRandIndex = GenRandom(i, uOrignSize-1);

			// 置换元素下标
			std::swap(tmpVec[i], tmpVec[uRandIndex]);
			randVec.push_back(tmpVec[i]);
			//if (tmpVec[i] == 0)
			//{
			//	continue;
			//}
			++uRandCount;
		}

		return;
	}