算法思路参考 :
质数筛法 : http://blog.csdn.net/program_think/article/details/7032600
在驱动层实现了一个质数筛法.
/// @file Function.h /// @brief 功能的实现 #ifndef __FUNCTION_H__ #define __FUNCTION_H__ #include <ntddk.h> #ifndef BYTE #define BYTE unsigned char #endif #define BYTE_BITS 8 #define BYTE_BITS_MASK(x) (1 << x) /// @fn PrintPerime /// @brief 打印 0~nMax 之间的质数, 用筛法实现 void PrintPerime(size_t nMax); /// @fn MakePerime /// @brief 制作质数Buffer void MakePerime(size_t nMax, BYTE * pcPerime, size_t nBufLenPerime); /// @fn ShowPerime /// @brief 打印质数Buffer void ShowPerime(size_t nMax, BYTE * pcPerime, size_t nBufLenPerime); /// @fn IsNumberPerime /// @brief 判断一个数是否是质数 BOOLEAN IsNumberPerime(size_t nNumber, BYTE * pcPerime, size_t nBufLenPerime); /// @fn IsNumberPerimeFlag /// @brief 判断一个数是否是质数标记 BOOLEAN IsNumberPerimeFlag(size_t nNumber, BYTE * pcPerime, size_t nBufLenPerime); /// @fn SetMultipleValue /// @brief 设置nNumber倍数的值为bVal void SetMultipleValue(size_t nNumber, BOOLEAN bVal, BYTE * pcPerime, size_t nBufLenPerime); /// @fn SetNumberValue /// @brief 设置nNumber的值为bVal void SetNumberValue(size_t nNumber, BOOLEAN bVal, BYTE * pcPerime, size_t nBufLenPerime); /// @fn IsNumberNeedSkip /// @brief 是否为需要逃过判断的数, 0, 1, 不需要判断质数 BOOLEAN IsNumberNeedSkip(size_t nNumber); #endif
/// @file Function.c /// @brief 功能的实现 #include "Function.h" void PrintPerime(size_t nMax) { /// 用1Bit代表一个数, 1Byte代表8个数, 用N Bytes 代表 0~nMax size_t nByteNumber = (nMax - nMax % 8) / 8 + ((0 == (nMax % 8)) ? 0 : 1); BYTE * pcPerime = ExAllocatePoolWithTag(PagedPool, nByteNumber, 'PRIM'); if (NULL == pcPerime) { DbgPrint("NULL == pcPerime\r\n"); return; } memset(pcPerime, 0xff, nByteNumber); ///< 假设所有的数都是质数 /// 设置0, 1不是素数为初始条件 SetNumberValue(0, FALSE, pcPerime, nByteNumber); SetNumberValue(1, FALSE, pcPerime, nByteNumber); MakePerime(nMax, pcPerime, nByteNumber); ShowPerime(nMax, pcPerime, nByteNumber); ExFreePool(pcPerime); } void MakePerime(size_t nMax, BYTE * pcPerime, size_t nBufLenPerime) { /// pcPerime 给定的值都是质数标记 size_t nLoop = 0; ///< Buffer的循环 size_t nLoopByte = 0; ///< Buffer中字节的循环 size_t nNumberCur = 0; ///< 当前位代表的数字, 如果是质数, 直接打印出来 for (nLoop = 0; nLoop <nBufLenPerime; nLoop++) { for (nLoopByte = 0; nLoopByte < BYTE_BITS; nLoopByte++) { if (!IsNumberPerime(nNumberCur, pcPerime, nBufLenPerime)) SetNumberValue(nNumberCur, FALSE, pcPerime, nBufLenPerime); SetMultipleValue(nNumberCur, FALSE, pcPerime, nBufLenPerime); ///< 每个数的倍数都不是质数 if (nNumberCur++ >= nMax) break; } } } BOOLEAN IsNumberNeedSkip(size_t nNumber) { return ((0 == nNumber) || (1 == nNumber)); } void SetNumberValue(size_t nNumber, BOOLEAN bVal, BYTE * pcPerime, size_t nBufLenPerime) { size_t nBytesPosBit = nNumber % BYTE_BITS; ///< 在该字节的位(位置) size_t nBytesPos = (nNumber - nBytesPosBit) / BYTE_BITS; ///< 在Buffer中的字节位置 if (bVal) *(pcPerime + nBytesPos) |= BYTE_BITS_MASK(nBytesPosBit); else *(pcPerime + nBytesPos) &= ~(BYTE_BITS_MASK(nBytesPosBit)); } void SetMultipleValue(size_t nNumber, BOOLEAN bVal, BYTE * pcPerime, size_t nBufLenPerime) { size_t nLoop = 0; ///< Buffer的循环 size_t nLoopByte = 0; ///< Buffer中字节的循环 size_t nNumberCur = 0; ///< 当前位代表的数字, 如果是质数, 直接打印出来 size_t nBytesPosBit = 0; ///< 在该字节的位(位置) size_t nBytesPos = 0; ///< 在Buffer中的字节位置 if (IsNumberNeedSkip(nNumber)) return; nBytesPosBit = nNumber % BYTE_BITS; nBytesPos = (nNumber - nBytesPosBit) / BYTE_BITS; nNumberCur = nBytesPos * BYTE_BITS + nBytesPosBit; for (nLoop = nBytesPos; nLoop <nBufLenPerime; nLoop++) { for (nLoopByte = nBytesPosBit; nLoopByte < BYTE_BITS; nLoopByte++) { if (nNumberCur <= nNumber) ///< 不包括设置nNumber { nNumberCur++; continue; } if (0 == (nNumberCur % nNumber)) { /// 当前数能被nNumber整除, 是nNumber的倍数 SetNumberValue(nNumberCur, bVal, pcPerime, nBufLenPerime); } nNumberCur++; } nBytesPosBit = 0; ///< 除了第一次使用, 都是从0开始 } } BOOLEAN IsNumberPerimeFlag(size_t nNumber, BYTE * pcPerime, size_t nBufLenPerime) { size_t nBytesPosBit = nNumber % BYTE_BITS; ///< 在该字节的位(位置) size_t nBytesPos = (nNumber - nBytesPosBit) / BYTE_BITS; ///< 在Buffer中的字节位置 if (IsNumberNeedSkip(nNumber)) return FALSE; return (0 == (*(pcPerime + nBytesPos) & BYTE_BITS_MASK(nBytesPosBit))) ? FALSE : TRUE; } BOOLEAN IsNumberPerime(size_t nNumber, BYTE * pcPerime, size_t nBufLenPerime) { BOOLEAN bIsPerime = TRUE; size_t nPos = 0; size_t nPosMax = 0; size_t nBytesPosBit = nNumber % BYTE_BITS; ///< 在该字节的位(位置) size_t nBytesPos = (nNumber - nBytesPosBit) / BYTE_BITS; ///< 在Buffer中的字节位置 if (!IsNumberPerimeFlag(nNumber, pcPerime, nBufLenPerime)) return FALSE; ///< 如果已经被前面的操作置为"非质数", 直接返回"非质数" /// 在nNumber之前的数都已经正确的标记了是否为质数 /// 只有一半以下的数, 有可能被整除 nPosMax = (size_t)((nNumber - (nNumber % 2)) / 2); for (nPos = 2; nPos <= nPosMax; nPos++) { if (!IsNumberPerimeFlag(nPos, pcPerime, nBufLenPerime)) ///< 不是质数不用整除 continue; if ((nNumber % nPos) == 0) { bIsPerime = FALSE; break; } } return bIsPerime; } void ShowPerime(size_t nMax, BYTE * pcPerime, size_t nBufLenPerime) { size_t nLoop = 0; ///< Buffer的循环 size_t nLoopByte = 0; ///< Buffer中字节的循环 size_t nNumberCur = 0; ///< 当前位代表的数字, 如果是质数, 直接打印出来 for (nLoop = 0; nLoop <nBufLenPerime; nLoop++) { for (nLoopByte = 0; nLoopByte < BYTE_BITS; nLoopByte++) { if ((*(pcPerime + nLoop) & BYTE_BITS_MASK(nLoopByte)) > 0) DbgPrint("%d\r\n", nNumberCur); if (nNumberCur++ >= nMax) break; } } }
/// @file sys.c /// @brief 驱动主程序 #include <ntddk.h> #include "Function.h" #define MODULE_NAME L"DrvDemo" #define DRIVER_NAME MODULE_NAME L".sys" #define DEVICE_NAME_GLOBAL L"\\\\.\\" MODULE_NAME #define DEVICE_NAME L"\\device\\" MODULE_NAME #define LINK_NAME L"\\dosDevices\\" MODULE_NAME NTSTATUS DispatchCommon(PDEVICE_OBJECT pDeviceObject, PIRP pIrp); VOID DriverUnload(PDRIVER_OBJECT pDriverObject); NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegPath) { size_t nIndex = 0; /// 找出40000以内的素数(筛法) size_t nReqPerimeMax = 40000; ///< 求质数的范围上限 NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_OBJECT pDeviceObject = NULL; UNICODE_STRING ustrDeviceName = {0}; UNICODE_STRING ustrLinkName = {0}; DbgPrint(">> DriverEntry\r\n"); RtlInitUnicodeString(&ustrDeviceName, DEVICE_NAME); RtlInitUnicodeString(&ustrLinkName, LINK_NAME); ntStatus = IoCreateDevice( pDriverObject, 0, &ustrDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject); if (!NT_SUCCESS(ntStatus)) { DbgPrint("<< DriverEntry : error IoCreateDevice\r\n"); return ntStatus; } pDeviceObject->Flags |= DO_BUFFERED_IO; ntStatus = IoCreateSymbolicLink( &ustrLinkName, &ustrDeviceName); if (!NT_SUCCESS(ntStatus)) { DbgPrint("<< DriverEntry : error IoDeleteDevice\r\n"); IoDeleteDevice(pDeviceObject); return ntStatus; } for(nIndex = 0; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++) { pDriverObject->MajorFunction[nIndex] = DispatchCommon; } pDriverObject->DriverUnload = DriverUnload; PrintPerime(nReqPerimeMax); /// 找出nReqPerimeMax以内的素数(筛法) DbgPrint("<< DriverEntry\r\n"); return STATUS_SUCCESS; } VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { UNICODE_STRING ustrLinkName = {0}; DbgPrint(">> DriverUnload\r\n"); RtlInitUnicodeString(&ustrLinkName, LINK_NAME); IoDeleteDevice(pDriverObject->DeviceObject); IoDeleteSymbolicLink(&ustrLinkName); DbgPrint("<< DriverUnload\r\n"); } NTSTATUS DispatchCommon(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
实验截图: