问题描述
我不熟悉 PHP 代码。我想将 PHP code 实现的 UUID V1 转换为 C#。我尝试了很多方法,但都失败了。哪部分代码有问题?
此 C# 代码生成错误的 GUID fa570fa10-3b235-472b-500-1ebc212c87e0
,参数 node
为 138417599493834080(结果可能因 Unix 日期时间而异)。当我将方法 Hex2Dec
更改为 here 时,它会生成 393031383131343830-3234313135-3138323139-313238-1ebc212c87e0
。我对错误的代码没有更多的想法。请帮我解决。
public static function v1($node)
{
// nano second time (only micro second precision) since start of UTC
$time = microtime(true) * 10000000 + 0x01b21dd213814000;
$time = pack("H*",sprintf('%016x',$time));
$sequence = random_bytes(2);
$sequence[0] = chr(ord($sequence[0]) & 0x3f | 0x80); // variant bits 10x
$time[0] = chr(ord($time[0]) & 0x0f | 0x10); // version bits 0001
if (!empty($node)) {
// non hex string identifier
if (is_string($node) && preg_match('/[^a-f0-9]/is',$node)) {
// base node off md5 hash for sequence
$node = md5($node);
// set multicast bit not IEEE 802 MAC
$node = (hexdec(substr($node,2)) | 1) . substr($node,2,10);
}
if (is_numeric($node))
$node = sprintf('%012x',$node);
$len = strlen($node);
if ($len > 12)
$node = substr($node,12);
else if ($len < 12)
$node .= str_repeat('0',12 - $len);
} else {
// base node off random sequence
$node = random_bytes(6);
// set multicast bit not IEEE 802 MAC
$node[0] = chr(ord($node[0]) | 1);
$node = bin2hex($node);
}
return bin2hex($time[4] . $time[5] . $time[6] . $time[7]) // time low
. '-' . bin2hex($time[2] . $time[3]) // time med
. '-' . bin2hex($time[0] . $time[1]) // time hi
. '-' . bin2hex($sequence) // seq
. '-' . $node; // node
}
这是 C# 部分
public static string MD5(this string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 crypto = System.Security.Cryptography.MD5.Create())
{
byte[] hashBytes = crypto.ComputeHash(Encoding.ASCII.GetBytes(input));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
sb.Append(hashBytes[i].ToString("x2"));
return sb.ToString();
}
}
public static string GenerateGuidV1(string node)
{
var xtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 10000000 + 0x01b21dd213814000;
var time = Pack(xtime.ToString("x"));
var sequence = new byte[2];
sequence[0] = (byte)((char)sequence[0] & 0x3f | 0x80); // variant bits 10x
time[0] = (byte)((char)time[0] & 0x0f | 0x10); // version bits 0001
if (!string.IsNullOrWhiteSpace(node))
{
// non hex string identifier
if (!IsNumeric(node) && Regex.IsMatch(node,"/[^a-f0-9]/is",RegexOptions.IgnoreCase))
//if (preg_match('/[^a-f0-9]/is',$node))
{
// base node off md5 hash for sequence
//$node = md5($node);
node = node.MD5();
// set multicast bit not IEEE 802 MAC
//$node = (hexdec(substr($node,10);
node = (int.Parse(node.Substring(0,2),NumberStyles.Hexnumber) | 1) + node.Substring(2,10);
}
if (IsNumeric(node))
node = Convert.ToInt64(node).ToString("x"); //sprintf('%012x',$node);
var len = node.Length;
if (len > 12)
node = node.Substring(0,12); //substr($node,12);
else if (len < 12)
node += string.Concat(Enumerable.Repeat("0",12 - len));//str_repeat('0',12 - $len);
}
else
{
// base node off random sequence
var seqNode = new byte[6];//$node = random_bytes(6);
// set multicast bit not IEEE 802 MAC
seqNode[0] = (byte)((char)node[0] | 1);//$node[0] = chr(ord($node[0]) | 1);
node = Convert.ToInt16(seqNode[0].ToString(),2).ToString("x");//bin2hex($node);
}
return Bin2Hex(time[4].ToString() + time[5].ToString() + time[6].ToString() + time[7].ToString()) // time low
+ '-'+ Bin2Hex(time[2].ToString() + time[3].ToString()) // time med
+ '-'+ Bin2Hex(time[0].ToString() + time[1].ToString()) // time hi
+ '-'+ Bin2Hex(sequence[0].ToString() + sequence[1].ToString()) // seq
+ '-'+ node; // node
}
private static string Bin2Hex(string value)
{
return Convert.ToInt64(value).ToString("x");
//byte[] bytes = Encoding.GetEncoding(1252).GetBytes(value);
//string hexString = "";
//for (int ii = 0; ii < bytes.Length; ii++)
//{
// hexString += bytes[ii].ToString("x2");
//}
//return hexString;
}
private static byte[] Pack(string hex)
{
hex = hex.Replace("-","");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2,16);
}
return raw;
}
private static bool IsNumeric(string value) => value.All(char.IsNumber);
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)