メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcSemiRealRandom.c

説明を見る。
00001 
00010 #include "dkcSemiRealRandom.h"
00011 #include "dkcOS.h"
00012 #include "dkcStdio.h"
00013 
00014 #ifdef _MSC_VER
00015 #   pragma warning(disable:4055)
00016 #endif
00017 
00018 
00019 
00020 #define dkcdSRR_PATH_SIZE (sizeof(wchar_t) * dkcdMAXPATH_BUFFER)
00021 
00022 typedef 
00023 DWORD (WINAPI *GetTempPathA_FT)(
00024     DWORD nBufferLength,
00025     LPSTR lpBuffer
00026     );
00027 
00028 typedef 
00029 DWORD (WINAPI *GetTempPathW_FT)(
00030     DWORD nBufferLength,
00031     LPWSTR lpBuffer
00032     );
00033 
00034 
00035 typedef 
00036 UINT (WINAPI *GetTempFileNameA_FT)(
00037     LPCSTR lpPathName,
00038     LPCSTR lpPrefixString,
00039     UINT uUnique,
00040     LPSTR lpTempFileName
00041     );
00042 
00043 typedef 
00044 UINT (WINAPI *GetTempFileNameW_FT)(
00045     LPCWSTR lpPathName,
00046     LPCWSTR lpPrefixString,
00047     UINT uUnique,
00048     LPWSTR lpTempFileName
00049     );
00050 
00051 
00052 static DKC_INLINE int load_dll(DKC_SEMI_REAL_RANDOM *p,BOOL isNT){
00053     DKC_DLL *pdll = dkcLoadLibrary("kernel32.dll");
00054     if(NULL==pdll)
00055         return edk_FAILED;
00056 
00057     if(isNT){
00058         p->fpGetTempFileName =  dkcGetProcAddress(pdll,"GetTempFileNameW");
00059         p->fpGetTempPath =          dkcGetProcAddress(pdll,"GetTempPathW");
00060     }else{
00061         p->fpGetTempFileName = dkcGetProcAddress(pdll,"GetTempFileNameA");
00062         p->fpGetTempPath =          dkcGetProcAddress(pdll,"GetTempPathA");
00063     }
00064     //p->fpQueryPerformanceCounter = dkcGetProcAddress(pdll,"QueryPerformanceCounter");
00065     dkcmFORCE_NOT_ASSERT(
00066         p->fpGetTempFileName == NULL ||
00067         p->fpGetTempPath == NULL
00068     );
00069 
00070     p->pDLL = pdll;
00071     return edk_SUCCEEDED;
00072 }
00073 
00074 DKC_SEMI_REAL_RANDOM *WINAPI dkcAllocSemiRealRandomWin32()
00075 {
00076     DKC_SEMI_REAL_RANDOM *ptr;
00077     DKC_GENERIC_FILESYSTEM *pfs;
00078     BOOL isNT = dkcIsOSNT();
00079     if(isNT)
00080     {//Windows NT
00081         pfs = dkcAlloc_UNICODE_FileSystem();
00082     }else{
00083         pfs = dkcAlloc_SJIS_FileSystem();
00084     }
00085     
00086     ptr = dkcAllocSemiRealRandomFromGFS(pfs);
00087     if(NULL==ptr){
00088         dkcFreeGenericFileSystem(&pfs);
00089         return NULL;
00090     }
00091     //余分に確保しておく・・・
00092     ptr->pPath = dkcAllocate(dkcdSRR_PATH_SIZE);
00093     if(NULL==ptr->pPath){
00094         goto End;
00095     }
00096 
00097     if(DKUTIL_FAILED(load_dll(ptr,isNT))){
00098         goto End;
00099     }
00100     
00101     ptr->mIsNT = isNT;
00102     //successful
00103     return ptr;
00104 End:
00105     dkcFreeSemiRealRandom(&ptr);
00106     return NULL;
00107 
00108     /*
00109     DKC_SEMI_REAL_RANDOM *ptr;
00110     pfs = dkcAlloc_SJIS_FileSystem();
00111     
00112     ptr = dkcAllocSemiRealRandomFromGFS(pfs);
00113     if(NULL==ptr){
00114         dkcFreeGenericFileSystem(&pfs);
00115         return NULL;
00116     }
00117     //successful
00118     return ptr;*/
00119 }
00120 
00121 
00122 DKC_SEMI_REAL_RANDOM *WINAPI dkcAllocSemiRealRandomFromGFS(DKC_GENERIC_FILESYSTEM *pa)
00123 {
00124     DKC_SEMI_REAL_RANDOM *p;
00125     if(NULL==pa){
00126         return NULL;
00127     }
00128     p = dkcAllocate(sizeof(DKC_SEMI_REAL_RANDOM));
00129     if(NULL==p){
00130         return NULL;
00131     }
00132     p->mpObj = pa;
00133     return p;
00134 }
00135 
00136 
00137 int WINAPI dkcFreeSemiRealRandom(DKC_SEMI_REAL_RANDOM **pp)
00138 {
00139     DKC_SEMI_REAL_RANDOM *p = *pp;
00140     if(NULL==pp || NULL==p)
00141         return edk_FAILED;
00142     
00143     dkcFreeGenericFileSystem(&(p->mpObj));
00144     return dkcFree(pp);
00145 }
00146 
00147 static DKC_INLINE int process(DKC_GENERIC_FILESYSTEM *gfs,const void *filename){
00148     size_t ws;
00149     char buff[1];
00150     int r = dkcGenericFileSystemOpen(gfs,edkcBinaryMode | edkcWriteMode,filename); 
00151     if(DKUTIL_FAILED(r))    return r;
00152 
00153     dkcGenericFileSystemWrite(gfs,buff,sizeof(buff),&ws);
00154     
00155     dkcGenericFileSystemClose(gfs);
00156 
00157     dkcGenericFileSystemDeleteFile(gfs,filename);
00158     return edk_SUCCEEDED;
00159 }
00160 
00161 static BOOL generate(DKC_SEMI_REAL_RANDOM *ptr,uint32 *value32){
00162 #ifdef WIN32
00163     DKC_INT64_STRUCT hd;
00164     uint32 temp;
00165     QueryPerformanceCounter(&hd); 
00166     temp = hd.u.LowPart;
00167 
00168     if(DKUTIL_FAILED(process(ptr->mpObj,ptr->pPath))){
00169         return FALSE;
00170     }
00171 
00172     QueryPerformanceCounter(&hd);
00173     *value32 = (hd.LowPart ^ temp);
00174     return TRUE;
00175 #else
00176 
00177 
00178 #endif
00179 }
00180 
00182 static uint32 test(DKC_SEMI_REAL_RANDOM *ptr,size_t test_count,size_t min_,size_t max_)
00183 {
00184     uint8 bits[dkcdSEMI_REAL_RANDOM_BITS];
00185     uint8 prior_bits[dkcdSEMI_REAL_RANDOM_BITS];
00186     uint32 various[dkcdSEMI_REAL_RANDOM_BITS];
00187     uint32 val;
00188     int randRshift,randLshift;
00189     int i;
00190     size_t j;
00191 
00192     memset(various,0,sizeof(uint32) * dkcdSEMI_REAL_RANDOM_BITS);
00193 
00194     for(j=0;j<test_count;j++)
00195     {
00196         if(FALSE==generate(ptr,&val))
00197             return 0xFFFFFFFF;
00198 
00199         for(i=0;i<dkcdSEMI_REAL_RANDOM_BITS;i++)
00200         {
00201             bits[i]=(uint8)(val & 1);
00202             val = val >> 1;
00203             various[i] += ( bits[i] != prior_bits[i] );
00204             prior_bits[i]=bits[i];
00205         }
00206     }
00207 
00208     randRshift=255;
00209     randLshift=-1;
00210     for(i=0;i<dkcdSEMI_REAL_RANDOM_BITS;i++)
00211     {
00212         if((various[i]>=min_)&&(various[i]<=max_))
00213         {
00214             if(i < randRshift)
00215                 randRshift=i;
00216             
00217             if(i >= randLshift)
00218                 randLshift=i-randRshift+1;
00219         }
00220         else break;
00221     }
00222     if(randRshift==255) return 0xFFFFFFFF;
00223     if(randLshift<=0)       return 0xFFFFFFFF;
00224     
00225     ptr->mLeftShift = randLshift;
00226     ptr->mRightShift = randRshift;
00227 
00228     return (uint32)randLshift;
00229 }
00230 
00231 int WINAPI dkcSemiRealRandomInit(DKC_SEMI_REAL_RANDOM *ptr)
00232 {
00233 #ifdef WIN32
00234 
00235     GetTempPathA_FT pGTPA;
00236     //char *pstr;
00237 
00238     GetTempPathW_FT pGTPW;
00239     //wchar_t *pwstr;
00240     
00241     if(ptr->mIsNT){
00242         pGTPW = (GetTempPathW_FT)ptr->fpGetTempPath;
00243         dkcmFORCE_NOT_ASSERT(dkcdMAXPATH < pGTPW(0,ptr->pPath));
00244 
00245         if(pGTPW(dkcdMAXPATH,ptr->pPath)==0)
00246              return edk_FAILED; //テンポラリファイルフォルダを取得
00247 
00248         //仮のテンポラリファイル。ちゃんとやるならGetTempFileNameで。
00249         if(DKUTIL_FAILED(dkc_wcscat2(ptr->pPath,dkcdSRR_PATH_SIZE,dkcdSRR_TEMP_FILE_NAME_W)))
00250         { 
00251             return edk_FAILED;
00252         }
00253 
00254     }else{//Win9x
00255         pGTPA = (GetTempPathA_FT)ptr->fpGetTempPath;
00256         dkcmFORCE_NOT_ASSERT(dkcdMAXPATH < pGTPA(0,ptr->pPath));
00257 
00258         if(pGTPA(dkcdMAXPATH,ptr->pPath)==0)
00259              return edk_FAILED; //テンポラリファイルフォルダを取得
00260 
00261         //仮のテンポラリファイル。ちゃんとやるならGetTempFileNameで。
00262         if(DKUTIL_FAILED(dkc_strcat2(ptr->pPath,dkcdSRR_PATH_SIZE,dkcdSRR_TEMP_FILE_NAME)))
00263         { 
00264             return edk_FAILED;
00265         }
00266     }
00267     {
00268         int i;
00269         for(i=0;i<dkcdSEMI_REAL_RANDOM_TRIAL_AND_ERROR_LIMIT;)//64回も行って成功しないは無いだろう・・・
00270         {
00271             if(0xFFFFFFFF==test(ptr,128,40,60)){
00272                 i++;
00273             }else{
00274                 break;
00275             }
00276         }
00277         if(!(i<64))
00278         {
00279             return edk_FAILED;
00280         }
00281     }
00282 
00283     return edk_SUCCEEDED;
00284 #else
00285 
00286 
00287 #endif
00288 
00289 }
00290 
00291 
00292 
00293 BOOL WINAPI dkcSemiRealRandomGet32(DKC_SEMI_REAL_RANDOM *ptr,uint32 *value32)
00294 {
00295     uint32 tmp=0;
00296     uint32 val;
00297     int totalbit=0;
00298     size_t i,j;
00299     for(j=0;j<dkcdSEMI_REAL_RANDOM_TRIAL_AND_ERROR_LIMIT;j++)
00300     {
00301         if(FALSE==generate(ptr,&val))
00302             return FALSE;
00303 
00304         val = val >> ptr->mRightShift;
00305         for(i=0;i<ptr->mLeftShift;i++)
00306         {
00307             tmp+=val & 1;
00308             val=val >> 1;
00309             totalbit++;
00310             if(totalbit>=32){
00311                 *value32 = tmp;
00312                 goto End;
00313             }
00314             tmp=tmp<<1;
00315         }
00316     }
00317 
00318 End:
00319     if(!(j<dkcdSEMI_REAL_RANDOM_TRIAL_AND_ERROR_LIMIT))
00320     {
00321         return FALSE;
00322     }
00323     return TRUE;
00324 }
00325 
00326 uint8 WINAPI dkcSemiRealRandomGet1(DKC_SEMI_REAL_RANDOM *ptr)
00327 {
00328 #ifdef WIN32
00329     uint32 val;
00330     generate(ptr,&val);
00331     return (uint8) ( (val >> ptr->mRightShift ) & 1) ;
00332 
00333 #else
00334 
00335 
00336 #endif
00337 
00338 
00339 
00340 }
00341 
00342 
00343 
00344 #ifdef _MSC_VER
00345 #   pragma warning(default:4055)
00346 #endif
00347 

dkutil_cに対してTue Feb 22 02:01:48 2005に生成されました。 doxygen 1.3.6