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