【代码】生成一个电脑硬件指纹【C#版本】

【代码】生成一个电脑硬件指纹【C#版本】

编码文章call10242025-09-03 22:14:138A+A-

采用C#语言实现。

特性:

跨平台(Windows / Linux / macOS)无需管理员权限 的 C# 实现,功能与 Go 版本保持一致:

  • 采集 CPU 特性 + 主板 UUID + 第一块物理磁盘序列号 + 第一块启用网卡 MAC
  • SHA-256 并取前 32 位十六进制字符作为脱敏硬件指纹
  • 完全使用 托管代码 / WMI / sysfs / IOKit 包装库,不调用 shell

项目结构(单文件即可编译)

HardwareId.csproj
Program.cs

1. HardwareId.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <!-- 跨平台硬件信息库 -->
  <ItemGroup>
    <PackageReference Include="System.Management" Version="8.0.0" />       <!-- Windows WMI -->
    <PackageReference Include="Hardware.Info" Version="15.0.0" />          <!-- 跨平台磁盘 / 网卡 -->
  </ItemGroup>
</Project>

2. Program.cs(完整代码,含中文注释)

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Hardware.Info;   // NuGet: Hardware.Info
using System.Management; // 仅 Windows 下用到

class Program
{
    static void Main()
    {
        try
        {
            string hwId = StableHardwareID();
            Console.WriteLine(hwId);
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(#34;获取硬件指纹失败: {ex}");
            Environment.Exit(1);
        }
    }

    /// <summary>
    /// 生成跨平台稳定且脱敏的硬件指纹。
    /// 步骤:CPU 特性 → 主板 UUID → 主硬盘序列号 → 第一块启用网卡 MAC
    /// 拼接后 SHA-256,取前 32 位十六进制字符。
    /// </summary>
    static string StableHardwareID()
    {
        var sb = new StringBuilder();

        // 1) CPU 特性:Vendor + Family + Model + Stepping
        sb.Append(GetCpuFeatureString()).Append('|');

        // 2) 主板 UUID(Windows WMI;Linux/macOS 读取 sysfs/IOKit)
        sb.Append(GetMotherboardUuid()).Append('|');

        // 3) 第一块非可移动磁盘序列号
        sb.Append(GetFirstDiskSerial()).Append('|');

        // 4) 第一块启用中、非回环 MAC 地址
        sb.Append(GetFirstActiveMac());

        // 5) SHA-256 并取前 32 位
        using var sha = SHA256.Create();
        byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString()));
        return Convert.ToHexString(hash).Substring(0, 32).ToLowerInvariant();
    }

    #region 私有辅助函数

    /// <summary>
    /// 获取 CPU 的 Vendor + Family + Model + Stepping
    /// </summary>
    static string GetCpuFeatureString()
    {
        var hi = new HardwareInfo();
        hi.RefreshCPUList();
        var cpu = hi.CpuList.FirstOrDefault()
                  ?? throw new Exception("无法获取 CPU 信息");
        return #34;{cpu.Manufacturer}-{cpu.Family}-{cpu.Model}-{cpu.Stepping}";
    }

    /// <summary>
    /// 主板 UUID(Windows 走 WMI;其余平台由 Hardware.Info 提供)
    /// </summary>
    static string GetMotherboardUuid()
    {
        if (OperatingSystem.IsWindows())
        {
            using var mc = new ManagementClass("Win32_ComputerSystemProduct");
            using var moc = mc.GetInstances();
            var uuid = moc.Cast<ManagementObject>()
                          .Select(m => m["UUID"]?.ToString())
                          .FirstOrDefault(u => !string.IsNullOrWhiteSpace(u));
            return uuid ?? throw new Exception("无法读取主板 UUID");
        }
        else
        {
            var hi = new HardwareInfo();
            hi.RefreshMotherboardList();
            return hi.MotherboardList.FirstOrDefault()?.SerialNumber
                   ?? throw new Exception("无法读取主板 UUID");
        }
    }

    /// <summary>
    /// 第一块非可移动、非 USB 磁盘的序列号
    /// </summary>
    static string GetFirstDiskSerial()
    {
        var hi = new HardwareInfo();
        hi.RefreshDriveList();
        var disk = hi.DriveList
                     .FirstOrDefault(d => !d.IsRemovable && d.Size > 0)
                     ?? throw new Exception("未找到物理磁盘");
        return disk.SerialNumber?.Trim() ?? throw new Exception("磁盘无序列号");
    }

    /// <summary>
    /// 第一块启用中、非回环网卡的 MAC 地址(去掉冒号并小写)
    /// </summary>
    static string GetFirstActiveMac()
    {
        var hi = new HardwareInfo();
        hi.RefreshNetworkAdapterList();
        var nic = hi.NetworkAdapterList
                    .FirstOrDefault(n => n.OperationalStatus == "Up" &&
                                         !n.MACAddress.StartsWith("00:00:00"))
                    ?? throw new Exception("未找到可用 MAC 地址");
        return nic.MACAddress.Replace(":", "").ToLowerInvariant();
    }

    #endregion
}

3. 编译 & 运行

# 还原依赖
dotnet restore

# 运行(Windows / Linux / macOS 均可)
dotnet run

输出示例(32 位十六进制,已脱敏):

3e8f2c4a7b91c0e5d8e3f1a2b9c4d7f6

与原 Go 实现对照

功能

Go 实现

C# 实现

CPU 信息

gopsutil

HardwareInfo.CpuList

主板 UUID

host.Info().HostID

WMI / HardwareInfo.MotherboardList

磁盘序列号

ghw

HardwareInfo.DriveList

MAC 地址

gopsutil

HardwareInfo.NetworkAdapterList

哈希

SHA-256

System.Security.Cryptography

跨平台

管理员权限

不需要

不需要

如需进一步扩展(缓存、在线校验、加密传输),可直接在 StableHardwareID() 结果之上继续封装。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4