注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

uuid的使用  

2014-02-24 20:25:15|  分类: LINUX编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

uuid的使用

在项目中难免会用到唯一的标识,这时候儿UUID是一个不错的选择。但是这个东西也有一个问题,就是转换起来有点儿麻烦。其实最近主要是在如何使用它的角度上在费心思,所以耽误了不少的时间。

总结下来有以下几种情况:

一、win下:

Windows下提供了一个函数可以生成一个GUID。需要使用的头文件 "objbase.h",需要链接的库ole32.lib

HRESULT CoCreateGuid(GUID * pguid);

a)然后转成字符串形式,即常见的xxxxx-xxxx-xxxx-xxxx-xxxxxxx这种情形:

有下面两个函数:

StringFromIID:把IID结构形式转换为字符串形式

StringFromGUID2:把GUID结构形式转换为字符串形式

举个例子:

  GUID *guid = (GUID *)rs.GetValue( col );

 

  WCHAR *pBuf = new WCHAR[48];       //很配存储文字串的空间

  ::StringFromGUID2(*guid, pBuf, 48);

 

  pField->put_AsString( pBuf ); //应用转换得到的文字串

 

  delete []pBuf;

b)字符串转回GUID

CLSIDFromProgID,这个函数不太熟悉,就不举例子了。大家有兴趣可以自己去网上查找。

二、LINUX

 apt-get install uuid-dev

安装完成后会在/usr/include/ 下有一个uuid文件夹,其中则包含了uuid.h头文件。在/usr/lib/ 下有几个libuuid*的链接库文件,包括静态和动态链接库。

打开uuid.h你会发现有一个uuid_generate(uuid_t out) 的函数声明。我们可以通过调用这个函数来生成UUID

uuid_generate(reinterpret_cast<unsigned char *>(&guid));

这个提供了下面的一些函数:

void uuid_clear(uuid_t uu);

 

/* compare.c */

int uuid_compare(const uuid_t uu1, const uuid_t uu2);

 

/* copy.c */

void uuid_copy(uuid_t dst, const uuid_t src);

 

/* gen_uuid.c */

void uuid_generate(uuid_t out);

void uuid_generate_random(uuid_t out);

void uuid_generate_time(uuid_t out);

int uuid_generate_time_safe(uuid_t out);

 

/* isnull.c */

int uuid_is_null(const uuid_t uu);

 

/* parse.c */

int uuid_parse(const char *in, uuid_t uu);

 

/* unparse.c */

void uuid_unparse(const uuid_t uu, char *out);

void uuid_unparse_lower(const uuid_t uu, char *out);

void uuid_unparse_upper(const uuid_t uu, char *out);

 

/* uuid_time.c */

time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);

int uuid_type(const uuid_t uu);

int uuid_variant(const uuid_t uu);

这个的例子太简单了,所以就不再举了,另外,大家可以在这下面这个网址上看上面的函数的源码:

http://www.oschina.net/code/explore/glusterfs/contrib/uuid/parse.c

三、自定义书写

自定义书写主要是从字符串形式转回到数组以及从数组转到字符串形式:

先说转到字符串:

std::string   UUIDToString(uuid_t ud)

{

         char buf[64] = {0};

         GUID guid;

#ifdef __GNUC__

         snprintf(

#else

         _snprintf_s(

#endif

                            buf,

                            sizeof(buf),

                            "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",

                            guid.gd.Data1, guid.gd.Data2, guid.gd.Data3,

                            guid.gd.Data4[0], guid.gd.Data4[1],

                            guid.gd.Data4[2], guid.gd.Data4[3],

                            guid.gd.Data4[4], guid.gd.Data4[5],

                            guid.gd.Data4[6], guid.gd.Data4[7]);

 

     return std::string(buf);

}

 

然后是字符串到数组:

bool UuidControl::StringToUUIDCharArray(const std::string &sGuid,GUID&guid)

{

         bool bRet = false;

         const char *szGUID = sGuid.c_str();

         memset(&guid, 0, sizeof(guid));//_stscanf--swscanf_s sscanf_s

         int nRet =

                   sscanf(szGUID,

                   "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",

                   &guid.gd.Data1,

                   &guid.gd.Data2,

                   &guid.gd.Data3,

                   &guid.gd.Data4[0], &guid.gd.Data4[1],

                   &guid.gd.Data4[2], &guid.gd.Data4[3], &guid.gd.Data4[4], &guid.gd.Data4[5], &guid.gd.Data4[6], &guid.gd.Data4[7]);

 

         return bRet;

}

但是从现在来看,还是以库自身带有的为好。

附录:

LINUX中的uuid操作的源码:

static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt)

{

         struct uuid uuid;

 

         uuid_unpack(uu, &uuid);

         sprintf(out, fmt,

                   uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,

                   uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,

                   uuid.node[0], uuid.node[1], uuid.node[2],

                   uuid.node[3], uuid.node[4], uuid.node[5]);

}

 

void uuid_unparse_lower(const uuid_t uu, char *out)

{

         uuid_unparse_x(uu, out, fmt_lower);

}

 

void uuid_unparse_upper(const uuid_t uu, char *out)

{

         uuid_unparse_x(uu, out, fmt_upper);

}

 

void uuid_unparse(const uuid_t uu, char *out)

{

         uuid_unparse_x(uu, out, FMT_DEFAULT);

}

 

 

#include <stdlib.h>

#include <stdio.h>

#include <ctype.h>

#include <string.h>

 

#include "uuidP.h"

 

int uuid_parse(const char *in, uuid_t uu)

{

         struct uuid        uuid;

         int            i;

         const char        *cp;

         char          buf[3];

 

         if (strlen(in) != 36)

                   return -1;

         for (i=0, cp = in; i <= 36; i++,cp++) {

                   if ((i == 8) || (i == 13) || (i == 18) ||

                       (i == 23)) {

                            if (*cp == '-')

                                     continue;

                            else

                                     return -1;

                   }

                   if (i== 36)

                            if (*cp == 0)

                                     continue;

                   if (!isxdigit(*cp))

                            return -1;

         }

         uuid.time_low = strtoul(in, NULL, 16);

         uuid.time_mid = strtoul(in+9, NULL, 16);

         uuid.time_hi_and_version = strtoul(in+14, NULL, 16);

         uuid.clock_seq = strtoul(in+19, NULL, 16);

         cp = in+24;

         buf[2] = 0;

         for (i=0; i < 6; i++) {

                   buf[0] = *cp++;

                   buf[1] = *cp++;

                   uuid.node[i] = strtoul(buf, NULL, 16);

         }

 

         uuid_pack(&uuid, uu);

         return 0;

}

所以说好多的问题其实最终的解决思路还是一致的。

  评论这张
 
阅读(1676)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017