c# 获取机器唯一识别码的示例

目录
  • 前言
  • 原理
  • 建议
  • 实现
  • 补充
  • 补充2

前言

在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为MAC地址是不会变的,但是现在各种改,特别是使用无线上网卡,MAC地址插一次变一次,所以这样使用MAC就没有什么意义了,怎么办,又开始求助Google,最后找到一个折中的方案

原理

通过获取主板、处理器、BIOS、mac、显卡、硬盘等的ID生成唯一识别码

建议

1、使用那些不经常更换的模块来生成识别码。

2、如果经常更换MAC,显卡,硬盘,则不要使用这些ID。

3、确保使用static变量在整个应用来保存唯一识别码。

实现

注意引用System.Management

using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
 /// <summary>
 /// Generates a 16 byte Unique Identification code of a computer
 /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
 /// </summary>
 public class FingerPrint
 {
 private static string fingerPrint = string.Empty;
 public static string Value()
 {
  if (string.IsNullOrEmpty(fingerPrint))
  {
  fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " +
  biosId() + "\nBASE >> " + baseId()
    //+"\nDISK >> "+ diskId() + "\nVIDEO >> " +
  videoId() +"\nMAC >> "+ macId()
     );
  }
  return fingerPrint;
 }
 private static string GetHash(string s)
 {
  MD5 sec = new MD5CryptoServiceProvider();
  ASCIIEncoding enc = new ASCIIEncoding();
  byte[] bt = enc.GetBytes(s);
  return GetHexString(sec.ComputeHash(bt));
 }
 private static string GetHexString(byte[] bt)
 {
  string s = string.Empty;
  for (int i = 0; i < bt.Length; i++)
  {
  byte b = bt[i];
  int n, n1, n2;
  n = (int)b;
  n1 = n & 15;
  n2 = (n >> 4) & 15;
  if (n2 > 9)
   s += ((char)(n2 - 10 + (int)'A')).ToString();
  else
   s += n2.ToString();
  if (n1 > 9)
   s += ((char)(n1 - 10 + (int)'A')).ToString();
  else
   s += n1.ToString();
  if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
  }
  return s;
 }
 #region Original Device ID Getting Code
 //Return a hardware identifier
 private static string identifier
 (string wmiClass, string wmiProperty, string wmiMustBeTrue)
 {
  string result = "";
  System.Management.ManagementClass mc =
 new System.Management.ManagementClass(wmiClass);
  System.Management.ManagementObjectCollection moc = mc.GetInstances();
  foreach (System.Management.ManagementObject mo in moc)
  {
  if (mo[wmiMustBeTrue].ToString() == "True")
  {
   //Only get the first one
   if (result == "")
   {
   try
   {
    result = mo[wmiProperty].ToString();
    break;
   }
   catch
   {
   }
   }
  }
  }
  return result;
 }
 //Return a hardware identifier
 private static string identifier(string wmiClass, string wmiProperty)
 {
  string result = "";
  System.Management.ManagementClass mc =
 new System.Management.ManagementClass(wmiClass);
  System.Management.ManagementObjectCollection moc = mc.GetInstances();
  foreach (System.Management.ManagementObject mo in moc)
  {
  //Only get the first one
  if (result == "")
  {
   try
   {
   result = mo[wmiProperty].ToString();
   break;
   }
   catch
   {
   }
  }
  }
  return result;
 }
 private static string cpuId()
 {
  //Uses first CPU identifier available in order of preference
  //Don't get all identifiers, as it is very time consuming
  string retVal = identifier("Win32_Processor", "UniqueId");
  if (retVal == "") //If no UniqueID, use ProcessorID
  {
  retVal = identifier("Win32_Processor", "ProcessorId");
  if (retVal == "") //If no ProcessorId, use Name
  {
   retVal = identifier("Win32_Processor", "Name");
   if (retVal == "") //If no Name, use Manufacturer
   {
   retVal = identifier("Win32_Processor", "Manufacturer");
   }
   //Add clock speed for extra security
   retVal += identifier("Win32_Processor", "MaxClockSpeed");
  }
  }
  return retVal;
 }
 //BIOS Identifier
 private static string biosId()
 {
  return identifier("Win32_BIOS", "Manufacturer")
  + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
  + identifier("Win32_BIOS", "IdentificationCode")
  + identifier("Win32_BIOS", "SerialNumber")
  + identifier("Win32_BIOS", "ReleaseDate")
  + identifier("Win32_BIOS", "Version");
 }
 //Main physical hard drive ID
 private static string diskId()
 {
  return identifier("Win32_DiskDrive", "Model")
  + identifier("Win32_DiskDrive", "Manufacturer")
  + identifier("Win32_DiskDrive", "Signature")
  + identifier("Win32_DiskDrive", "TotalHeads");
 }
 //Motherboard ID
 private static string baseId()
 {
  return identifier("Win32_BaseBoard", "Model")
  + identifier("Win32_BaseBoard", "Manufacturer")
  + identifier("Win32_BaseBoard", "Name")
  + identifier("Win32_BaseBoard", "SerialNumber");
 }
 //Primary video controller ID
 private static string videoId()
 {
  return identifier("Win32_VideoController", "DriverVersion")
  + identifier("Win32_VideoController", "Name");
 }
 //First enabled network card ID
 private static string macId()
 {
  return identifier("Win32_NetworkAdapterConfiguration",
  "MACAddress", "IPEnabled");
 }
 #endregion
 }
}

补充

现在遇到一些平板等简陋的机型,竟然获取到的所有设备标识都一样(除了mac),最后只好在本地再生成一个软件自身的标识,然后每次在计算标识的时候附带上,这样不会再重复了吧。

代码如下:

private static string localkey()
 {
  string path=Environment.CurrentDirectory + "client.key";
  if (File.Exists(path))
  {
  StreamReader sr = new StreamReader(path);
  string key= sr.ReadLine();
  sr.Close();
  return key;
  }
  else
  {
  StreamWriter sw = File.CreateText(path);
  string key = Guid.NewGuid().ToString();
  sw.WriteLine(key);
  sw.Close();
  return key;
  }
 }

可以再把该文件设为隐藏等手段,防止用户误操作。

补充2

文件容易被误删,还可以写入注册表,除非系统重装,但是需要以管理员权限运行

class RegistryHelper
 {
 const string _uriDeviecId = "SOFTWARE\\YourCompany\\YouApp";
 public static string GetDeviceId()
 {
  string ret = string.Empty;
  using (var obj = Registry.LocalMachine.OpenSubKey(_uriDeviecId, false))
  {
  if (obj != null)
  {
   var value = obj.GetValue("DeviceId");
   if (value != null)
   ret = Convert.ToString(value);
  }
  }
  return ret;
 }

 public static void SetDeviceId()
 {
  using (MD5 md5Hash = MD5.Create())
  {
  byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(DateTime.Now.ToString()));
  StringBuilder sBuilder = new StringBuilder();
  for (int i = 0; i < data.Length; i++)
  {
   sBuilder.Append(data[i].ToString("x2"));
  }

  string id = sBuilder.ToString();
  using (var tempk = Registry.LocalMachine.CreateSubKey(_uriDeviecId))
  {
   tempk.SetValue("DeviceId", id);
  }
  }
 }
 }

以上就是c# 获取机器唯一识别码的示例的详细内容,更多关于c# 获取机器识别码的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#获取机器码的方法详解(机器名,CPU编号,硬盘编号,网卡mac等)

    本文实例讲述了C#获取机器码的方法.分享给大家供大家参考,具体如下: using System.Runtime.InteropServices; using System.Management; using System; public class HardwareInfo { //取机器名 public string GetHostName() { return System.Net.Dns.GetHostName(); } //取CPU编号 public String GetCpuID()

  • asp.net(c#)捕捉搜索引擎蜘蛛和机器人

    下面是访问日志文件2008-8-13 14:43:22 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 1.1.4322) 2008-8-13 14:43:27 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 1.1.4322) 2008-8-13 14:44:18 Mozi

  • C#机器入门学习之判断日报是否合格详解

    前言 简单来说机器学习的核心步骤在于"获取学习数据:选择机器算法:定型模型:评估模型,预测模型结果",下面本人就以判断日报内容是否合格为例为大家简单的阐述一下C#的机器学习. 第一步:问题分析 根据需求可以得出我们的模型是以日报的内容做为学习的特征确定的,然后通过模型判断将该目标对象预测为是否符合标准(合格与不合格),简单来说就是一种分类场景(此场景结果属于二元分类,不是A就是B),那么也就确定了核心算法为分类算法当然还有其它的分类算法有兴趣的可以自己去了解一下在这里就不多做说明了.

  • C#图像识别 微信跳一跳机器人

    更新 GitHub中所有类库的源码已经转换为C#版本. 准备 IDE:VisualStudio Language:C#/VB.NET GitHub:AutoJump.NET 本文将向你介绍一种通过图像识别实现"跳一跳"机器人的方法. 第一节 图像识别 文中提到的所有方法和步骤只涉及简单的向量计算. 需要用到哪些计算? 比较像素点的颜色 求向量集合的中心 计算颜色的相似度 一个RGB颜色可以看作一个三维向量 比较两个颜色的相似度可以计算它们的欧几里得距离 也可以直接比较它们的夹角:夹角越

  • c# 获取机器唯一识别码的示例

    目录 前言 原理 建议 实现 补充 补充2 前言 在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为MAC地址是不会变的,但是现在各种改,特别是使用无线上网卡,MAC地址插一次变一次,所以这样使用MAC就没有什么意义了,怎么办,又开始求助Google,最后找到一个折中的方案 原理 通过获取主板.处理器.BIOS.mac.显卡.硬盘等的ID生成唯一识别码 建议 1.使用那些不经常更换的模块来生成识别码. 2.如果经常更换MAC,显卡,硬盘,则不要使用这些ID. 3.确保使用stati

  • 获取Android系统唯一识别码的方法

    本文实例讲述了获取Android系统唯一识别码的方法.分享给大家供大家参考.具体如下: 在计算机上,我们习惯用MAC地址来标志一台计算机.在Android设备上,可以用IMIE或者Android ID来标志一个设备. 看一下Android上怎样获取这样的信息. 一个是TelephonyManager的getDeviceId,另外一个是Settings.System的ANDROID_ID 这里贴一段测试代码: package com.npc4.android.imie; import androi

  • iOS获取设备唯一标识的8种方法

    8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可以改变设备的 UDID),移动网络可以利用 UDID 来识别移动设备. 许多开发者把 UDID 跟用户的真实姓名.密码.住址.其它数据关联起来,网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据,同时大部分应用确实在频繁传输 UDID 和私人信息. 为了避免集体诉讼,苹果最终决

  • 浅谈android获取设备唯一标识完美解决方案

    本文介绍了浅谈android获取设备唯一标识完美解决方案,分享给大家,具体如下: /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 * * 渠道标志为: * 1,andriod(a) * * 识别符来源标志: * 1, wifi mac地址(wifi): * 2, IMEI(imei): * 3, 序列号(sn): * 4, id:随机码.若前面的都取不到时,则随机生成一个随机码,需要缓存. * * @param context * @return */ p

  • iOS 获取设备唯一标示符的方法详解

    在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式--读取设备的UUID(Universally Unique Identifier)并通过KeyChain记录. 首先iOS中获取设备唯一标示符的方法一直随版本的更新而变化.iOS 2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符.好景不长,因为该唯一标识符与手机一一对应,苹果觉得

  • php生成局部唯一识别码LUID的代码

    UUID(Universally Unique Identifier),GUID都是希望在整个时空范围内能产生唯一识别码,这在分布式计算环境下是必要的. 然而,如果仅仅是想在一个受限定的局部环境下,想生成一个"局部唯一识别码",使用UUID就是杀鸡用牛刀,这个"局部唯一识别码",我称之为LUID(Local Unique Identifier) 比如我在用php开发网站程序时,为避免用户同时多次打开同一个网页导致session名称冲突问题, 就希望保存的sessio

  • php获取网页请求状态程序示例

    对于网页返回状态代码一般情况下我们都会去查自己网站状态码是不是200或错误页面是不是404代码,并且多数情况下我们的查看方法就是使用站长工具或ff浏览器等来查看,极少有人想到自己写一个查看状态代码的功能. 本文就此简述php获取网页请求状态程序示例如下: 方法一,使用 fsockopen(不推荐使用curl_getinfo!) 复制代码 代码如下: function get_http_code($url="localhost", $port=80, $fsock_timeout=10)

  • jquery获取元素索引值index()示例

    jquery获取元素索引值index()方法: jquery的index()方法 搜索匹配的元素,并返回相应元素的索引值,从0开始计数. 如果不给 .index() 方法传递参数,那么返回值就是这个jQuery对象集合中第一个元素相对于其同辈元素的位置. 如果参数是一组DOM元素或者jQuery对象,那么返回值就是传递的元素相对于原先集合的位置. 如果参数是一个选择器,那么返回值就是原先元素相对于选择器匹配元素中的位置.如果找不到匹配的元素,则返回-1. 复制代码 代码如下: <ul> <

  • 详解Android获取设备唯一ID的几种方式

    先来看看几种比较单一的方式: IMEI 方式:TelephonyManager.getDeviceId(): 问题 范围:只能支持拥有通话功能的设备,对于平板不可以. 持久性:返厂,数据擦除的时候不彻底,保留了原来的标识. 权限:需要权限:Android.permission.READ_PHONE_STATE bug: 有些厂家的实现有bug,返回一些不可用的数据  Mac地址 ACCESS_WIFI_STATE权限 有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回

  • golang 获取明天零点的时间戳示例

    实例如下所示: package main import ( "fmt" "time" ) func main() { timeStr := time.Now().Format("2006-01-02") fmt.Println(timeStr) //使用Parse 默认获取为UTC时区 需要获取本地时区 所以使用ParseInLocation t, _ := time.ParseInLocation("2006-01-02 15:04:

随机推荐