来自字符串的GUID

时间:2016-04-11 14:17:37

标签: c++ visual-c++ guid c++98

假设我们有一个字符串

  

“{GUID}”

其中GUID是{}中的标准GUID。我需要获得与给定字符串匹配的GUID类型的变量。它是用Visual C ++完成的,如果重要的话版本很旧(6.0)。

首先,我尝试使用GUIDFromString功能,但无法将其导入,因此发现UuidFromString。但是我真的陷入了从unsigned char到char等所有这些强制转换,没有C ++背景这很难。也许有些人会非常友好地帮助我。感谢。

2 个答案:

答案 0 :(得分:1)

GUID指的是一些唯一的识别号,可以使用某种算法生成 - 您可以找到一些关于微软算法的描述 - 他们试图获取时间戳,网卡号和一个,并混合一个独特的GUID。

我检查了什么 - 没有人阻止你创建自己的"独特的"生成算法 - 但您需要以某种方式确保您的唯一生成算法不会与现有算法发生冲突,这种可能性极小。此算法生成的GUID也不应与您自己的GUID冲突。

在浏览互联网时,我发现了一些生成此类指南的方法 - 例如 - Microsoft Office:http://support.microsoft.com/kb/2186281

从Strings生成GUID时,您可以使用String.GetHashCode32,甚至可以计算20字节sha-1哈希字符串。 (第一个更容易,但第二个创建更多字节用于GUID)。

然后开始填写GUID,尽可能多地填写它。

以下是一些演示代码,让您了解这个想法:

using System;

class Program
{
    /// <summary>
    /// http://stackoverflow.com/questions/53086/can-i-depend-on-the-values-of-gethashcode-to-be-consistent
    /// 
    /// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static unsafe int GetHashCode32(string s)
    {
        fixed (char* str = s.ToCharArray())
        {
            char* chPtr = str;
            int num = 0x15051505;
            int num2 = num;
            int* numPtr = (int*)chPtr;
            for (int i = s.Length; i > 0; i -= 4)
            {
                num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
                if (i <= 2)
                {
                    break;
                }
                num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
                numPtr += 2;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }
    /// <summary>
    /// Generates new product code for particular product / install package.
    /// </summary>
    /// <param name="productName">Logical product name for which to generate</param>
    /// <param name="productVersion">Product version in form "1.0.0"</param>
    /// <returns></returns>
    static public String GenerateProductCode( String productName, String productVersion )
    {
        String[] vparts = productVersion.Split(".".ToCharArray());
        int[] verParts = new int [3] { 1, 0, 0 };
        int i = 0; 
        foreach( String v in vparts )
        {
            Int32.TryParse(v, out verParts[i++] );
            if( i >= 3 ) break;
        }

        //
        //  "MyCompanyName", "1.0.2" will generate guid like this: {F974DC1F-0001-0000-0002-10009CD45A98}
        //                                                         ^ Hash over manufacturer name - "MyCompanyName"
        //                                                                  ^ Version - "<major>-<minor>-<build>" in hexadecimal
        //                                                                                 ^ 1 as for 64 bit.
        //                                                                                  ^000 - just reserved for future needs
        //                                                                                     ^ Hash over product name
        //
        //  See also similar generation schemes - http://support.microsoft.com/kb/2186281.
        //
        String newGuid = String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-1000{4:X8}", GetHashCode32("MyCompanyName"), verParts[0], verParts[1], verParts[2], GetHashCode32(productName));
        newGuid = "{" + newGuid + "}";
        return newGuid;
    }

    static void Main()
    {
        String s = GenerateProductCode("MyProduct", "1.0.2");
        Console.WriteLine(s);
    }
}

将打印出来:

{F974DC1F-0001-0000-0002-10003618D1E1}

但是以类似的方式,您也可以在C ++中生成GUID - 最有可能使用sprintf()。

这是用于将String转换为哈希码的.NET兼容函数:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>


int GetHashCode32( const wchar_t* ps )
{
    int num = 0x15051505;
    int num2 = num;
    const wchar_t* s = ps;
    const char* chPtr=(const char*) ps;
    size_t numBuff = wcslen((wchar_t*) chPtr) * 2;
    int* numPtr = (int*)chPtr;

    for (int i = wcslen(s); i > 0; i -= 4)
    {
        num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
        if (i <= 2)
        {
            break;
        }
        num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
        numPtr += 2;
    }

    return (num + (num2 * 0x5d588b65));
}

void GetHash(const wchar_t* p)
{
    printf("'%S' = %08X", p, GetHashCode32(p));
    printf("\r\n");
}



void main(void)
{
    GetHash(L"testing");
    GetHash(L"MainClass::" __FUNCTIONW__);
    GetHash(L"1");
    GetHash(L"");

}

答案 1 :(得分:1)

好的,问题出在include和libs上。您需要包含X并链接RPC库:

<Rpc.h>

而且你可以使用#pragma comment (lib, "Rpcrt4.lib") 功能。请注意,您不需要在字符串表示中包含{和}。