34 行
1.2 KiB
Swift
34 行
1.2 KiB
Swift
|
|
import Foundation
|
|||
|
|
import CryptoKit
|
|||
|
|
|
|||
|
|
/// 错误指纹计算
|
|||
|
|
public enum Fingerprint {
|
|||
|
|
|
|||
|
|
/// 计算错误指纹
|
|||
|
|
public static func compute(type: String, message: String, stacktrace: String) -> String {
|
|||
|
|
let normalizedMessage = normalizeMessage(message)
|
|||
|
|
let topFrames = extractTopFrames(stacktrace, count: 3)
|
|||
|
|
|
|||
|
|
let payload = "\(type):\(normalizedMessage):\(topFrames)"
|
|||
|
|
let data = Data(payload.utf8)
|
|||
|
|
let hash = SHA256.hash(data: data)
|
|||
|
|
return hash.map { String(format: "%02x", $0) }.joined()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 归一化消息(数字替换为 N,长 hex 替换为 H)
|
|||
|
|
private static func normalizeMessage(_ message: String) -> String {
|
|||
|
|
var result = message
|
|||
|
|
// 替换数字
|
|||
|
|
result = result.replacingOccurrences(of: #"\d+"#, with: "N", options: .regularExpression)
|
|||
|
|
// 替换长 hex 字符串
|
|||
|
|
result = result.replacingOccurrences(of: #"[0-9a-fA-F]{8,}"#, with: "H", options: .regularExpression)
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 提取堆栈顶部帧
|
|||
|
|
private static func extractTopFrames(_ stacktrace: String, count: Int) -> String {
|
|||
|
|
let lines = stacktrace.split(separator: "\n").prefix(count)
|
|||
|
|
return lines.joined(separator: "|")
|
|||
|
|
}
|
|||
|
|
}
|