c# - 在 C# 中将 Guid 转换为 2 个 longs 并将 2 个 longs 转换为 Guid

标签 c# .net .net-core

Guid是128bits结构,long是Int64所以是64bits结构,因此Guid可以用来表示两个long,两个long可以存储在一个Guid中。

我一直在寻找一种可靠的方法来执行将 Guid 转换为 2 个 long 及其周围的方法,主要是为了获得一种向外部服务提供跟踪 id 的简单方法。

目标是获得一种可逆的方式来传入单个参数 2 longs,并稍后将其解码(当然,它不打算在另一端使用“解码”)。它就像外部服务的 session id。

最佳答案

警告:这些解决方案没有考虑字节序,因此结果可能因平台而异

利用 C# 7 的新特性,我提出了以下工具类,将 long、ulong、int、uint 转换为 Guid 和 reverse:

public static class GuidTools
{
    public static Guid GuidFromLongs(long a, long b)
    {
        byte[] guidData = new byte[16];
        Array.Copy(BitConverter.GetBytes(a), guidData, 8);
        Array.Copy(BitConverter.GetBytes(b), 0, guidData, 8, 8);
        return new Guid(guidData);
    }

    public static (long, long) ToLongs(this Guid guid)
    {
        var bytes = guid.ToByteArray();
        var long1 = BitConverter.ToInt64(bytes, 0);
        var long2 = BitConverter.ToInt64(bytes, 8);
        return (long1, long2);
    }

    public static Guid GuidFromULongs(ulong a, ulong b)
    {
        byte[] guidData = new byte[16];
        Array.Copy(BitConverter.GetBytes(a), guidData, 8);
        Array.Copy(BitConverter.GetBytes(b), 0, guidData, 8, 8);
        return new Guid(guidData);
    }

    public static (ulong, ulong) ToULongs(this Guid guid)
    {
        var bytes = guid.ToByteArray();
        var ulong1 = BitConverter.ToUInt64(bytes, 0);
        var ulong2 = BitConverter.ToUInt64(bytes, 8);
        return (ulong1, ulong2);
    }

    public static Guid GuidFromInts(int a, int b, int c, int d)
    {
        byte[] guidData = new byte[16];
        Array.Copy(BitConverter.GetBytes(a), guidData, 4);
        Array.Copy(BitConverter.GetBytes(b), 0, guidData, 4, 4);
        Array.Copy(BitConverter.GetBytes(c), 0, guidData, 8, 4);
        Array.Copy(BitConverter.GetBytes(d), 0, guidData, 12, 4);
        return new Guid(guidData);
    }

    public static (int, int , int, int) ToInts(this Guid guid)
    {
        var bytes = guid.ToByteArray();
        var a = BitConverter.ToInt32(bytes, 0);
        var b = BitConverter.ToInt32(bytes, 4);
        var c = BitConverter.ToInt32(bytes, 8);
        var d = BitConverter.ToInt32(bytes, 12);
        return (a, b, c, d);
    }

    public static Guid GuidFromUInts(uint a, uint b, uint c, uint d)
    {
        byte[] guidData = new byte[16];
        Array.Copy(BitConverter.GetBytes(a), guidData, 4);
        Array.Copy(BitConverter.GetBytes(b), 0, guidData, 4, 4);
        Array.Copy(BitConverter.GetBytes(c), 0, guidData, 8, 4);
        Array.Copy(BitConverter.GetBytes(d), 0, guidData, 12, 4);
        return new Guid(guidData);
    }

    public static (uint, uint, uint, uint) ToUInts(this Guid guid)
    {
        var bytes = guid.ToByteArray();
        var a = BitConverter.ToUInt32(bytes, 0);
        var b = BitConverter.ToUInt32(bytes, 4);
        var c = BitConverter.ToUInt32(bytes, 8);
        var d = BitConverter.ToUInt32(bytes, 12);
        return (a, b, c, d);
    }
}

还从那里找到了另一个解决方案:Converting System.Decimal to System.Guid

[StructLayout(LayoutKind.Explicit)]
struct GuidConverter
{
    [FieldOffset(0)]
    public decimal Decimal;
    [FieldOffset(0)]
    public Guid Guid;
    [FieldOffset(0)]
    public long Long1;
    [FieldOffset(8)]
    public long Long2;
}

private static GuidConverter _converter;
public static (long, long) FastGuidToLongs(this Guid guid)
{
    _converter.Guid = guid;
    return (_converter.Long1, _converter.Long2);
}
public static Guid FastLongsToGuid(long a, long b)
{
    _converter.Long1 = a;
    _converter.Long2 = b;
    return _converter.Guid;
}

关于c# - 在 C# 中将 Guid 转换为 2 个 longs 并将 2 个 longs 转换为 Guid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49372626/

相关文章:

C# 内存损坏错误

c# - 我怎样才能改进这个排序代码?

c# - ASP.Net Core Web API 中的返回文件

c# - 将 Entity Framework Core 实体转换为 SQL 字符串

c# - 正则表达式 - 电话号码(包括+,(,)和长度验证 - C#

c# - 调用 SuspensionManager.SaveAsync() 时出现异常

c# - 返回接口(interface)时如何找到真实类型?

c# - Sitecore Fast Query - 如何搜索包含特殊字符(例如撇号)的文本?

c# - 在 AxAcroPDF 中隐藏 pdf 工具栏

c# - 将现有的 docker 链接到外部配置文件和数据以在 C# 核心(linux 容器)中使用它