简单的BSON OID生成实现

时间:2024-04-20 21:35:27

简单的OID生成测试实现,只是简单的用用,切勿用于生产环境。

/* 应该使用大端序的,这里没有做转换
* ObjectId是12-byte BSON类型,其结构为:
*
* 4-byte 值为Unix时间戳,
* 3-byte 主机标识,
* 2-byte 进程ID
* 3-byte 计数值
*/ #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <process.h>
#include <Windows.h>
#else
#include <unistd.h>
#include <sys/utsname.h>
#endif /* 全局的主机标识(这个值可采用主机名散列得到) */
static unsigned char host[4] = {0,0,0,0};
/* 全局计数器(进程一个,要避免访问冲突,当前没有考虑) */
static int counter = 0;
/* 进程ID值 */
static unsigned short pid = 0; // 简单的将主机名进行散列
void hashhostname(const char* hostname)
{
host[0] = 0x41;
host[1] = 0xC6;
host[2] = 0x4E;
while(*hostname){
unsigned char v = *(hostname++);
host[0] += v >> 2;
host[1] += v >> 3;
host[2] += v >> 4;
}
} void create_oid()
{
time_t t = time(NULL); unsigned char oid[12];
*((int*)oid) = (int)t;
oid[4] = host[0];
oid[5] = host[1];
oid[6] = host[2];
oid[7] = pid;
oid[8] = pid >> 8;
oid[9] = counter;
oid[10] = counter >> 8;
oid[11] = counter >> 16;
// 输出
++counter;
counter &= 0xffffff;
int i=0;
while(i<12){
printf("%02X",oid[i++]);
}
putchar('\n');
} int main()
{
// 1、初始化主机标识和进程ID
#ifdef _WIN32
char buffer[512];
DWORD buflen = 512;
GetComputerNameA((LPSTR)buffer,&buflen);
buffer[511] = '\0';
puts(buffer);
hashhostname(buffer);
pid = (unsigned short)_getpid();
#else
struct utsname utn;
if(uname(&utn) < 0 ){
perror("uname");
return 0;
}else{
printf(" sysname:%s\n nodename:%s\n release:%s\n version:%s\n machine:%s\n \n",
utn.sysname,
utn.nodename,
utn.release,
utn.version,
utn.machine);
hashhostname(utn.nodename);
} pid = (unsigned short)getpid();
#endif
puts("-----------------------");
printf(" host=[%hhx,%hhx,%hhx]\n",host[0],host[1],host[2]);
printf(" pid = %hx\n",pid);
puts("-----------------------"); counter = 0xfffffe;
create_oid();
create_oid();
create_oid();
create_oid();
return 0;
}