# 设备指纹SDK

一个隐私友好的现代浏览器设备指纹库，使用浏览器信号生成稳定、高熵的设备标识符。

[English Version](./README.en.md)

## � 核心原理 (工作机制)

现代浏览器利用底层硬件（GPU、声卡）加速渲染和计算以优化性能。由于硬件制造商、驱动版本和操作系统抗锯齿策略的不同，即使是相同的文字和图形，在不同设备上渲染出的二进制数据也会存在肉眼极难察觉的微小差异。

设备指纹通过组合多种浏览器特征，生成一个能够尽量唯一标识该设备的哈希字符串。本 SDK 采用了 5 种信号源：

- 🎨 **Canvas 指纹** - 不同 GPU 和渲染引擎绘制图形时的细微差异
- 🔊 **Audio 指纹** - 音频堆栈处理波形的特征差异
- 💻 **硬件特征** - CPU 核心数、内存、平台、语言、时区等
- 🎮 **WebGL 指纹** - GPU 供应商、渲染器型号及 WebGL 参数
- 📝 **字体检测** - 系统已安装字体列表（20 种常见字体）

### 🔐 熵值估计

5 种信号源组合可提供约 38 bits 的熵值，理论上可以区分约 2740 亿台不同设备。

## 📦 安装

```bash
npm install device-fingerprint-js
```

## 🚀 使用

### 1. 基本使用（ES模块）

```javascript
import { generateFingerprint } from 'device-fingerprint-js';

// 生成指纹
const result = await generateFingerprint({
  canvas: true, // 启用 Canvas 指纹
  audio: true, // 启用 Audio 指纹
  webgl: true, // 启用 WebGL 指纹
  fonts: true, // 启用字体检测
  hardware: true, // 启用硬件特征
});

console.log(result.deviceId);
// 输出: "84e1b..." (16位稳定唯一 ID)
```

### 2. 通过script标签引入

```html
<!-- 引入SDK -->
<script src="path/to/device-fingerprint/dist/index.umd.js"></script>

<!-- 使用SDK -->
<script>
  // 调用generateFingerprint函数
  DeviceFingerprint.generateFingerprint({
    canvas: true,
    audio: true,
    webgl: true,
    fonts: true,
    hardware: true,
  })
    .then((result) => {
      console.log('Fingerprint result:', result);
      console.log('Device ID:', result.deviceId);
      // 处理结果...
    })
    .catch((error) => {
      console.error('Error generating fingerprint:', error);
    });
</script>
```

### 3. Vue.js 集成

#### Vue 3 组合式 API

```vue
<template>
  <div>
    <h1>设备指纹</h1>
    <p v-if="isLoading">正在生成指纹...</p>
    <p v-else>您的设备ID: {{ deviceId }}</p>
    <button @click="generate">重新生成</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { generateFingerprint } from 'device-fingerprint-js';

const deviceId = ref('');
const isLoading = ref(false);

async function generate() {
  isLoading.value = true;
  try {
    const result = await generateFingerprint();
    deviceId.value = result.deviceId;
  } catch (error) {
    console.error('生成指纹失败:', error);
  } finally {
    isLoading.value = false;
  }
}

// 挂载时生成
onMounted(() => {
  generate();
});
</script>
```

#### Vue 2 选项式 API

```vue
<template>
  <div>
    <h1>设备指纹</h1>
    <p v-if="isLoading">正在生成指纹...</p>
    <p v-else>您的设备ID: {{ deviceId }}</p>
    <button @click="generate">重新生成</button>
  </div>
</template>

<script>
import { generateFingerprint } from 'device-fingerprint-js';

export default {
  data() {
    return {
      deviceId: '',
      isLoading: false,
    };
  },
  mounted() {
    this.generate();
  },
  methods: {
    async generate() {
      this.isLoading = true;
      try {
        const result = await generateFingerprint();
        this.deviceId = result.deviceId;
      } catch (error) {
        console.error('生成指纹失败:', error);
      } finally {
        this.isLoading = false;
      }
    },
  },
};
</script>
```

### 3. React 集成

```jsx
import React, { useState, useEffect } from 'react';
import { generateFingerprint } from 'device-fingerprint-js';

function FingerprintComponent() {
  const [deviceId, setDeviceId] = useState('');
  const [isLoading, setIsLoading] = useState(true);

  async function generate() {
    setIsLoading(true);
    try {
      const result = await generateFingerprint();
      setDeviceId(result.deviceId);
    } catch (error) {
      console.error('生成指纹失败:', error);
    } finally {
      setIsLoading(false);
    }
  }

  useEffect(() => {
    generate();
  }, []);

  return (
    <div>
      <h1>设备指纹</h1>
      {isLoading ? (
        <p>正在生成指纹...</p>
      ) : (
        <>
          <p>您的设备ID: {deviceId}</p>
          <button onClick={generate}>重新生成</button>
        </>
      )}
    </div>
  );
}

export default FingerprintComponent;
```

## 📄 结果对象

```javascript
{
  deviceId: '84e1b...',       // 16位十六进制设备ID
  entropyScore: 38,           // 估计的熵值（位）
  generationTimeMs: 123,      // 生成耗时（毫秒）
  components: {               // 用于生成的原始组件
    canvas: 'abc123...',
    audio: '0.1234',
    webgl: 'NVIDIA Corporation|NVIDIA GeForce GTX...',
    fonts: 'Arial|Verdana|Times New Roman|...',
    hardware: { ... }
  },
  details: {                  // 额外的详细信息
    canvasDataUrl: 'data:image/png;base64,...',
    webgl: 'NVIDIA Corporation|NVIDIA GeForce GTX...',
    fonts: ['Arial', 'Verdana', 'Times New Roman', ...],
    hardware: {
      concurrency: 8,         // CPU核心数
      memory: 16,             // 内存（GB）
      platform: 'Win32',      // 平台
      language: 'en-US',      // 语言
      colorDepth: 24,         // 颜色深度
      pixelDepth: 24,         // 像素深度
      timezoneOffset: 480     // 时区偏移（分钟）
    }
  },
  _debug_featureString: 'canvas:abc123...;;audio:0.1234;;...' // 用于哈希的原始特征字符串
}
```

## 🕵️ 隐私与局限

- ✅ **隐私友好**
  SDK 仅采集设备硬件属性（如 GPU、声卡处理特征）和系统配置，不收集任何 IP、地理位置或具体设备账户等敏感隐私信息。

- ✅ **稳定持久**
  不依赖 cookie 或 localStorage，清理缓存或使用隐身模式通常不会改变 ID。采集逻辑已针对夏令时等环境波动进行了稳定性优化。

- ⚠️ **抗指纹浏览器**
  部分隐私浏览器（如 Tor、Brave）或 Safari 的“阻止跨站跟踪”功能会故意为 Canvas/Audio 添加随机噪点。这会导致每次生成的 ID 都不一样。这是正常的隐私保护机制。

## 📝 配置选项

```typescript
interface GenerateFingerprintOptions {
  canvas?: boolean; // 默认: true
  audio?: boolean; // 默认: true
  webgl?: boolean; // 默认: true
  fonts?: boolean; // 默认: true
  hardware?: boolean; // 默认: true
}
```

## 🛠️ 浏览器支持

- Chrome 60+ 版本
- Firefox 60+ 版本
- Safari 12+ 版本
- Edge 79+ 版本

## 📄 许可证

MIT 许可证

## 📚 技术细节

### 信号源

1. **Canvas 指纹**
   - 渲染混合字体、表情符号和各种混合模式的图形
   - 捕获画布不同区域的像素数据
   - 使用 MurmurHash3 进行高效哈希

2. **Audio 指纹**
   - 使用 Web Audio API 静默生成音频
   - 应用振荡器和压缩器效果
   - 捕获音频堆栈处理的细微差异

3. **WebGL 指纹**
   - 收集 GPU 供应商、渲染器和版本信息
   - 捕获 WebGL 参数值
   - 在可用时使用供应商特定扩展

4. **字体检测**
   - 测试 20 种常见系统字体
   - 使用画布测量检测字体可用性
   - 返回已安装字体的排序列表

5. **硬件特征**
   - CPU 核心数 (hardwareConcurrency)
   - 设备内存 (deviceMemory)
   - 平台信息
   - 语言设置
   - 颜色深度和像素深度
   - 时区偏移（稳定，已调整夏令时）

## 🔧 开发

```bash
# 安装依赖
npm install

# 构建 TypeScript
npm run build

# 监听模式
npm run dev
```

## 📦 包结构

```
device-fingerprint-js/
├── dist/                  # 构建输出文件
│   ├── index.js           # 主入口（ES 模块）
│   ├── index.umd.js       # UMD 格式（支持script标签引入）
│   ├── index.d.ts         # 类型定义
│   ├── index.js.map       # 源映射
│   └── index.d.ts.map     # 类型定义映射
├── src/                   # 源代码文件
│   ├── index.js           # 主实现
│   └── index.d.ts         # 类型定义
├── package.json           # 包配置
├── tsconfig.json          # TypeScript 配置
└── README.md              # 文档
```
