将 int 转换为加扰的 Guid 并返回
Convert int to scrambled Guid and back
我正在寻找一种将 int 转换为 Guid 的方法,但不能让下一个按顺序排列。例如,我有这个:
static void Main(string[] args)
{
var a = Int2Guid(1);
var b = Int2Guid(2);
}
public static Guid Int2Guid(int value)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
public static int Guid2Int(Guid value)
{
byte[] b = value.ToByteArray();
int bint = BitConverter.ToInt32(b, 0);
return bint;
}
这行得通,但我不希望数字是连续的,也不想出现连续的。从上面的例子中,我得到 a = {00000001-0000-0000-0000-000000000000}
,但是 b = {00000002-0000-0000-0000-000000000000}
。我想要 {48204b95-9cbb-4295-a6b1-cf05ebda9d0d}
.
有什么建议吗?
对于 Guid 需要 4 个整数或 16 个字节,您应该输入 4 个整数或 16 个字节。
我让 Int2Guid
输入 4 个整数。
public static Guid Int2Guid(int value, int value1, int value2, int value3)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
BitConverter.GetBytes(value1).CopyTo(bytes, 4);
BitConverter.GetBytes(value2).CopyTo(bytes, 8);
BitConverter.GetBytes(value3).CopyTo(bytes, 12);
return new Guid(bytes);
}
我让 Guid2Int
输出 int 数组。
public static int[] Guid2Int(Guid value)
{
byte[] b = value.ToByteArray();
int bint = BitConverter.ToInt32(b, 0);
var bint1 = BitConverter.ToInt32(b, 4);
var bint2 = BitConverter.ToInt32(b, 8);
var bint3 = BitConverter.ToInt32(b, 12);
return new[] {bint, bint1, bint2, bint3};
}
当我为Int2Guid
创建一个Guid并将其设置为Guid2Int
时,它可以回到原点。
static void Main(string[] args)
{
var guid = Guid.NewGuid();
var foo = Guid2Int(guid);
var a = Int2Guid(foo[0], foo[1], foo[2], foo[3]);
Console.WriteLine(a == guid); //true
}
不知道你是否需要
有一个很好的解决方案,使用 AES ECB 模式加密 guid,适用于 16 个字节(您在示例中提供的内容:
public class EncryptGUI
{
private Aes aes;
public EncryptGUI (byte[] key)
{
aes = Aes.Create ();
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
aes.Key = key;
}
public String encryptUID (byte[] guid)
{
ICryptoTransform aesDecryptor = aes.CreateDecryptor ();
byte[] result = aesDecryptor.TransformFinalBlock (guid, 0, guid.Length);
return ToHex (result);
}
public static string ToHex (byte[] data)
{
StringBuilder hex = new StringBuilder (data.Length * 2);
foreach (byte b in data)
hex.AppendFormat ("{0:x2}", b);
return hex.ToString ();
}
public static void Main (string[] args)
{
byte[] key = new byte[16];
EncryptGUI main = new EncryptGUI (key);
byte[] guid = new byte[16];
Console.Out.WriteLine (main.encryptUID (guid));
}
}
请注意,ECB 不使用 IV,这意味着您可以区分不同的 GUID(因为每个 GUID 将映射到一个密文)。但是密文应该与使用的块密码和密钥的安全性完全相同。
您可以通过使用 MD5 散列整数并将散列作为 Guid 的来源来实现:
int max = 10;
for (int i = 1; i < max + 1; i++)
{
MD5 md5 = MD5.Create();
Byte[] intBytes = BitConverter.GetBytes(i);
Byte[] hash = md5.ComputeHash(intBytes);
Console.WriteLine(new Guid(hash));
}
请注意,这不是一种加密安全方法。
我正在寻找一种将 int 转换为 Guid 的方法,但不能让下一个按顺序排列。例如,我有这个:
static void Main(string[] args)
{
var a = Int2Guid(1);
var b = Int2Guid(2);
}
public static Guid Int2Guid(int value)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
public static int Guid2Int(Guid value)
{
byte[] b = value.ToByteArray();
int bint = BitConverter.ToInt32(b, 0);
return bint;
}
这行得通,但我不希望数字是连续的,也不想出现连续的。从上面的例子中,我得到 a = {00000001-0000-0000-0000-000000000000}
,但是 b = {00000002-0000-0000-0000-000000000000}
。我想要 {48204b95-9cbb-4295-a6b1-cf05ebda9d0d}
.
有什么建议吗?
对于 Guid 需要 4 个整数或 16 个字节,您应该输入 4 个整数或 16 个字节。
我让 Int2Guid
输入 4 个整数。
public static Guid Int2Guid(int value, int value1, int value2, int value3)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
BitConverter.GetBytes(value1).CopyTo(bytes, 4);
BitConverter.GetBytes(value2).CopyTo(bytes, 8);
BitConverter.GetBytes(value3).CopyTo(bytes, 12);
return new Guid(bytes);
}
我让 Guid2Int
输出 int 数组。
public static int[] Guid2Int(Guid value)
{
byte[] b = value.ToByteArray();
int bint = BitConverter.ToInt32(b, 0);
var bint1 = BitConverter.ToInt32(b, 4);
var bint2 = BitConverter.ToInt32(b, 8);
var bint3 = BitConverter.ToInt32(b, 12);
return new[] {bint, bint1, bint2, bint3};
}
当我为Int2Guid
创建一个Guid并将其设置为Guid2Int
时,它可以回到原点。
static void Main(string[] args)
{
var guid = Guid.NewGuid();
var foo = Guid2Int(guid);
var a = Int2Guid(foo[0], foo[1], foo[2], foo[3]);
Console.WriteLine(a == guid); //true
}
不知道你是否需要
有一个很好的解决方案,使用 AES ECB 模式加密 guid,适用于 16 个字节(您在示例中提供的内容:
public class EncryptGUI
{
private Aes aes;
public EncryptGUI (byte[] key)
{
aes = Aes.Create ();
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
aes.Key = key;
}
public String encryptUID (byte[] guid)
{
ICryptoTransform aesDecryptor = aes.CreateDecryptor ();
byte[] result = aesDecryptor.TransformFinalBlock (guid, 0, guid.Length);
return ToHex (result);
}
public static string ToHex (byte[] data)
{
StringBuilder hex = new StringBuilder (data.Length * 2);
foreach (byte b in data)
hex.AppendFormat ("{0:x2}", b);
return hex.ToString ();
}
public static void Main (string[] args)
{
byte[] key = new byte[16];
EncryptGUI main = new EncryptGUI (key);
byte[] guid = new byte[16];
Console.Out.WriteLine (main.encryptUID (guid));
}
}
请注意,ECB 不使用 IV,这意味着您可以区分不同的 GUID(因为每个 GUID 将映射到一个密文)。但是密文应该与使用的块密码和密钥的安全性完全相同。
您可以通过使用 MD5 散列整数并将散列作为 Guid 的来源来实现:
int max = 10;
for (int i = 1; i < max + 1; i++)
{
MD5 md5 = MD5.Create();
Byte[] intBytes = BitConverter.GetBytes(i);
Byte[] hash = md5.ComputeHash(intBytes);
Console.WriteLine(new Guid(hash));
}
请注意,这不是一种加密安全方法。