This commit is contained in:
zyj
2025-09-13 10:22:49 +08:00
commit 002419a7ed
28 changed files with 1888 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
package browserfingerprint
import "fmt"
func GetChangeCanvasJavaScript(rgba [4]int) string {
return fmt.Sprintf(`
const getImageData = CanvasRenderingContext2D.prototype.getImageData;
const noisify = (canvas, context) => {
if (context) {
const shift = {
r: %d,
g: %d,
b: %d,
a: %d,
};
const width = canvas.width;
const height = canvas.height;
if (width && height) {
const imageData = getImageData.apply(context, [0, 0, width, height]);
for (let i = 0; i < height; i++)
for (let j = 0; j < width; j++) {
const n = i * (width * 4) + j * 4;
imageData.data[n + 0] = imageData.data[n + 0] + shift.r;
imageData.data[n + 1] = imageData.data[n + 1] + shift.g;
imageData.data[n + 2] = imageData.data[n + 2] + shift.b;
imageData.data[n + 3] = imageData.data[n + 3] + shift.a;
}
context.putImageData(imageData, 0, 0);
}
}
};
HTMLCanvasElement.prototype.toBlob = new Proxy(HTMLCanvasElement.prototype.toBlob, {
apply(target, self, args) {
noisify(self, self.getContext('2d'));
return Reflect.apply(target, self, args);
},
});
HTMLCanvasElement.prototype.toDataURL = new Proxy(HTMLCanvasElement.prototype.toDataURL, {
apply(target, self, args) {
noisify(self, self.getContext('2d'));
return Reflect.apply(target, self, args);
},
});
CanvasRenderingContext2D.prototype.getImageData = new Proxy(
CanvasRenderingContext2D.prototype.getImageData,
{
apply(target, self, args) {
noisify(self.canvas, self);
return Reflect.apply(target, self, args);
},
}
);
`, rgba[0], rgba[1], rgba[2], rgba[3])
}

View File

@@ -0,0 +1,42 @@
package browserfingerprint
import (
paramsTypes "go-account-register/types"
"math/rand"
"github.com/go-rod/rod"
)
type BrowserFingerprint struct {
}
func (b *BrowserFingerprint) SetBrowserFingerprint(page *rod.Page, params *paramsTypes.BrowserFingerprintParams) *rod.Page {
var p *rod.Page = page
if params.Canvas {
p = setCanvas(p)
}
if params.TimeZone != "" {
p = setTimezoneAndLangAndGeo(p, params)
}
return p
}
func setCanvas(page *rod.Page) *rod.Page {
// 注入噪声脚本
// 生成随机 RGBA 偏移值 (Go 端控制)
rgba := [4]int{
rand.Intn(10) - 5, // R: -5 ~ +4
rand.Intn(10) - 5, // G
rand.Intn(10) - 5, // B
rand.Intn(10) - 5, // A
}
// 使用更隐蔽的 Canvas 指纹修改方法
page.MustEvalOnNewDocument(GetChangeCanvasJavaScript(rgba))
return page
}
func setTimezoneAndLangAndGeo(page *rod.Page, params *paramsTypes.BrowserFingerprintParams) *rod.Page {
page.MustEvalOnNewDocument(GetChangeTimezoneJavaScript(params.TimeZone, params.Language, params.GeoLocation))
return page
}

View File

@@ -0,0 +1,98 @@
package browserfingerprint
import (
"fmt"
"log"
"time"
_ "time/tzdata"
)
func GetChangeTimezoneJavaScript(timezone string, lang string, geo string) string {
return fmt.Sprintf(`
(() => {
// 设置全局时区配置
window.__rodTZConfig = {
timeZone: '%s',
language: '%s',
geo: '%s'
};
// 覆盖 Date 对象
const OriginalDate = window.Date;
window.Date = function(...args) {
if (new.target) {
// 作为构造函数
if (args.length === 0) {
// 无参数调用时应用时区偏移
const now = new OriginalDate();
const targetOffset = -480; // %s 的 UTC 偏移(分钟)
return new OriginalDate(now.getTime() + (targetOffset - now.getTimezoneOffset()) * 60000);
}
return new OriginalDate(...args);
}
// 作为函数调用
return OriginalDate();
};
// 复制静态方法和属性
Object.defineProperties(Date, Object.getOwnPropertyDescriptors(OriginalDate));
// 覆盖 Date.now()
const origDateNow = Date.now;
Date.now = function() {
return origDateNow() + (%d * 60000); // 添加时区偏移
};
// 覆盖 getTimezoneOffset
const origGetTimezoneOffset = Date.prototype.getTimezoneOffset;
Date.prototype.getTimezoneOffset = function() {
return %d; // %s 的 UTC 偏移(分钟)
};
// 覆盖 Intl.DateTimeFormat
const origDateTimeFormat = Intl.DateTimeFormat;
Intl.DateTimeFormat = function(locales, options) {
options = options || {};
options.timeZone = options.timeZone || window.__rodTZConfig.timeZone;
return new origDateTimeFormat(locales, options);
};
// 覆盖 navigator 属性
Object.defineProperty(navigator, 'language', {
get: () => window.__rodTZConfig.language,
configurable: false
});
Object.defineProperty(navigator, 'languages', {
get: () => [window.__rodTZConfig.language],
configurable: false
});
// 覆盖控制台时区
if (console._timeZone) {
console._timeZone = window.__rodTZConfig.timeZone;
}
})();
`,
timezone,
lang,
geo,
timezone, // 用于注释
getUTCOffsetMinutes(timezone), // 时区偏移分钟数
getUTCOffsetMinutes(timezone), // 时区偏移分钟数
timezone)
}
// getUTCOffsetMinutes 获取时区的UTC偏移分钟数
func getUTCOffsetMinutes(timeZone string) int {
// 使用时区名称获取实际偏移
loc, err := time.LoadLocation(timeZone)
if err != nil {
log.Printf("无法加载时区 %s: %v, 使用默认值 -480", timeZone, err)
return -480 // 默认太平洋时间
}
// 获取当前时间的偏移
_, offset := time.Now().In(loc).Zone()
return -offset / 60 // 转换为分钟并取反
}