# Генерация отпечатка

Итак, если вы посетили предыдущую страницу, содержащую схему объекта Fingerprint, вы уже знаете, что это довольно громоздко.
К счастью, есть более простой способ сделать это.

Мы внедрили логику генерации отпечатков в наш инструмент — aemulari , который генерирует отпечатки точно так же, как и приложение Surfinite, когда вы нажимаете кнопку «Создать» на странице профиля. Команда для генерации отпечатка: generate-fp. Вот справочное сообщение:

$ ./aemulari generate-fp --help

Generate fingerprint usage:
  --os TEXT             Operating System (required), allowed values: "windows",
                        "linux", "macos"
  --os-version TEXT     OS version (optional). For Windows: "7", "8", "8.1", 
                        "10" and "11". For macOS: "11" (Big 
                        Sur), "12" (Monterey) and "13" (Ventura). For Linux it must be kernel 
                        version string like "5.15.0". Defaults: "10" for 
                        Windows, "13" for macOS and "5.15.0" for Linux
  --chrome-version TEXT Full Chrome version (optional, recommended), e.g. 
                        "106.0.5249.134". Default: the newest version packed 
                        with this version of aemulari. Might be outdated
  --pretty              Prettify JSON. Might be very handy for manual use when 
                        testing


Эта команда генерирует объект отпечатка с той же логикой, что и в приложении Surfinite, и возвращает JSON в качестве выходных данных.

Затем вы сможете использовать его для создания профиля. Или сначала установите собственные поля (например, экран или отключить подмену WebGL), а затем создайти профиль. Вот пример кода:

// Start aemulari to generate fingerprint
val process = ProcessBuilder(
    listOf(
        "/home/myuser/.surfinite/aemulari/aemulari",
        "generate-fp",
        "--os", "windows", // required
        "--os-version", "10", // optional
        "--chrome-version", "106.0.5249.134" // optional
    )
)
    .start()

// Read output. It is either fingerprint string or an error
val procOutput = process.inputStream.readAllBytes().decodeToString()

process.waitFor()

val exitCode = process.exitValue()
if (exitCode != 0) {
    println("Generate Fingerprint error. Exit code: $exitCode.")
    println(procOutput) // should contain error from aemulari
    return
}

// Create request JSON
val fingerprintObject = Json.parseToJsonElement(procOutput)
val clusterId = "62aad24955d7cb159cae7fae"
val profileRequest: JsonObject = buildJsonObject {
    put("parentId", clusterId) // you can also set group as parent
    put("name", "Test Profile")
    put("fingerprint", fingerprintObject)
}

val client = HttpClient(CIO) {
    install(ContentNegotiation) { json() }
}

// Create profile request
val response = client
    .post("$apiUrl/profiles?api_key=$apiKey") {
        contentType(ContentType.Application.Json)
        setBody(profileRequest)
    }
    .body<JsonObject>()

// Server returns profile object, so you can use it further
// in your app logic.
println("Profile ID: ${response["_id"]!!.jsonPrimitive}")