C/400

45. 絶対に重複しない GUID の生成の方法

ユニークな識別を行いたい場合に、重複しない何らかの文字列をどのようにして
生成すればよいだろうか ?
ユーザーによって連番を生成させるようにしても複数ユーザーからの同時操作によって
重複してしまう可能性は、かなりある。
ランダム関数によって整数を生成させたとしても重複しないという保証はどこにもない。
このように絶対、重複のない文字列のことを GUID (Globally Unique Idendifier)
と呼ぶが、OS にも UUID (Universal Unique Identifier ) を生成する機能がある。
UUID による 16桁の文字列の生成は絶対に世界中で重複しないことが IBM によって
保証されている。
16桁の重複しない文字列とは、思い当たるフシがあるのなら、あなたは相当、ILE に
精通しているだろう。
サービス・プログラム(*SRVPGM) の識別コードも 16桁の文字列を使用していて
32桁の HEXコードの文字列として良く知られている。
サービス・プログラム(*SRVPGM) の識別コードも UUID を利用しているとみて
間違いないだろう。
EnterpriseServer Ver5.1ではセッション管理が搭載されたがセッションの識別として
UUID が利用されている。
よくあるようにセッション管理bェ単なる自動生成では、重複の危険が大いにあり
セッション管理そのものが脆弱なものとなってしまうからである。
Ver5.1のセッション管理では UUID による堅牢なセッション識別が保証されている。

UUID の生成は マシンインターフェースAPI: _GENUUID によって行う。
_GENUUID は OS V5R1M0 で初めて紹介された API であるが V3R2M0 以降でも使用する
ことができる。

【 サンプルC/400 】
0001.00 #include <stdio.h>                                     
0002.00 #include <stdlib.h>                                    
0003.00 #include <string.h>                                    
0004.00 #include <mih/genuuid.h>                               
0005.00                                                        
0006.00 #define TRUE         0                                 
0007.00 #define FALSE       -1                                 
0008.00 void  _GENUUID(_UUID_Template_T* template);            
0009.00 char  m_UUID[33];          /* UUID */                  
0010.00                                                        
0011.00 void main(void){                                       
0012.00    int i, j;                                           
0013.00    _UUID_Template_T template;                          
0014.00                                                        
0015.00      printf("**** TESTUUID ****n");                    
0016.00      getchar();                                        
0017.00      memset(&template, 0, sizeof(_UUID_Template_T));   
0018.00      template.bytesProv = sizeof(_UUID_Template_T);    
0019.00      _GENUUID(&template); /* ユニーク ID を生成 */     
0020.00      memset(m_UUID, 0, sizeof(m_UUID));                
0021.00      j = 0;                                            
0022.00      for(i = 0; i<16; i++){/*for-loop*/             
0023.00        m_UUID[j] = template.uuid[i] | 0x0f;            
0024.00        switch(m_UUID[j]){/*switch*/                    
0025.00        case  0x0f: m_UUID[j] = '0'; break;             
0026.00        case  0x1f: m_UUID[j] = '1'; break;             
0027.00        case  0x2f: m_UUID[j] = '2'; break;             
0028.00        case  0x3f: m_UUID[j] = '3'; break;             
0029.00        case  0x4f: m_UUID[j] = '4'; break;             
0030.00        case  0x5f: m_UUID[j] = '5'; break;             
0031.00        case  0x6f: m_UUID[j] = '6'; break;             
0032.00        case  0x7f: m_UUID[j] = '7'; break;             
0033.00        case  0x8f: m_UUID[j] = '8'; break;             
0034.00        case  0x9f: m_UUID[j] = '9'; break;             
0035.00        case  0xaf: m_UUID[j] = 'A'; break;             
0036.00        case  0xbf: m_UUID[j] = 'B'; break;             
0037.00        case  0xcf: m_UUID[j] = 'C'; break;             
0038.00        case  0xdf: m_UUID[j] = 'D'; break;             
0039.00        case  0xef: m_UUID[j] = 'E'; break;             
0040.00        case  0xff: m_UUID[j] = 'F'; break;             
0041.00        }/*switch*/                                     
0042.00        j ++;                                     
0043.00        m_UUID[j] = template.uuid[i] | 0xf0;      
0044.00        switch(m_UUID[j]){/*switch*/              
0045.00        case  0xf0: m_UUID[j] = '0'; break;       
0046.00        case  0xf1: m_UUID[j] = '1'; break;       
0047.00        case  0xf2: m_UUID[j] = '2'; break;       
0048.00        case  0xf3: m_UUID[j] = '3'; break;       
0049.00        case  0xf4: m_UUID[j] = '4'; break;       
0050.00        case  0xf5: m_UUID[j] = '5'; break;       
0051.00        case  0xf6: m_UUID[j] = '6'; break;       
0052.00        case  0xf7: m_UUID[j] = '7'; break;       
0053.00        case  0xf8: m_UUID[j] = '8'; break;       
0054.00        case  0xf9: m_UUID[j] = '9'; break;       
0055.00        case  0xfa: m_UUID[j] = 'A'; break;       
0056.00        case  0xfb: m_UUID[j] = 'B'; break;       
0057.00        case  0xfc: m_UUID[j] = 'C'; break;       
0058.00        case  0xfd: m_UUID[j] = 'D'; break;       
0059.00        case  0xfe: m_UUID[j] = 'E'; break;       
0060.00        case  0xff: m_UUID[j] = 'F'; break;       
0061.00        }/*switch*/                               
0062.00        j ++;                                     
0063.00      }/*for-loop*/                      
0064.00                                         
0065.00    printf("m_UUID = %32sn", m_UUID);   
0066.00    getchar();                           
0067.00                                         
0068.00 }