Skip to main content

random

Function random 

Source
pub fn random() -> Identity
Expand description

Return a random preset identity.

Uses a simple entropy source based on the current system time so it requires no extra dependencies.

Examples found in repository?
examples/launch.rs (line 24)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let identity = match std::env::args().nth(1) {
20        Some(arg) => {
21            let id: u64 = arg.parse()?;
22            preset::get_by_id(id)?
23        }
24        None => preset::random(),
25    };
26
27    println!(
28        "Launching preset #{:?}: {:?} {} / {:?} / {}",
29        identity.id, identity.os, identity.os_version, identity.browser, identity.gpu.webgl_renderer
30    );
31
32    let _session = IdentitySession::launch(identity).await?;
33
34    println!("Browser is up with the identity applied.");
35    println!("Visit a detection site in the opened window (e.g. creepjs / bot.sannysoft.com).");
36    println!("Press Ctrl-C to quit.");
37
38    // Hold the process (and therefore the browser) open until interrupted.
39    tokio::signal::ctrl_c().await?;
40    println!("\nShutting down.");
41    Ok(())
42}
More examples
Hide additional examples
examples/verify.rs (line 15)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13    let identity = match std::env::args().nth(1) {
14        Some(arg) => preset::get_by_id(arg.parse()?)?,
15        None => preset::random(),
16    };
17    let url = std::env::args()
18        .nth(2)
19        .unwrap_or_else(|| "https://abrahamjuliot.github.io/creepjs/".to_string());
20
21    println!("preset #{:?}: {:?} / {:?}", identity.id, identity.os, identity.browser);
22
23    let mut session = IdentitySession::launch(identity).await?;
24    println!("launched, navigating to {url} ...");
25
26    // Collect page errors before anything else runs.
27    session.browser().add_init_script(rustenium::cdp::target_manager::InitScript {
28        page: Some(r#"window.__errs=[];
29            addEventListener('error', e => __errs.push('ERR ' + (e.message||e)));
30            addEventListener('unhandledrejection', e => __errs.push('REJ ' + (e.reason && (e.reason.message||e.reason))));
31        "#.into()),
32        worker: None,
33    }).await;
34
35    session.browser_mut().navigate(&url).await?;
36    println!("navigated; waiting for CreepJS to finish computing");
37
38    // CreepJS takes a while; poll for the widget rather than guessing a duration.
39    let mut rendered = false;
40    for _ in 0..40 {
41        tokio::time::sleep(Duration::from_secs(2)).await;
42        let probe = session
43            .browser_mut()
44            .evaluate_script("!!document.querySelector('.stealth-rating')", false)
45            .await;
46        if let Ok(v) = probe {
47            if format!("{:?}", v).contains("true") {
48                rendered = true;
49                break;
50            }
51        }
52        print!(".");
53    }
54    println!();
55    if !rendered {
56        println!("WARNING: stealth widget never rendered — page may be blocked or hung");
57    }
58    tokio::time::sleep(Duration::from_secs(3)).await;
59
60    let expr = r#"(() => {
61        const pct = (s) => { const e=document.querySelector(s); return e ? (e.textContent.match(/^\s*(\d+%)/)||['','?'])[1] : 'MISSING'; };
62        const flagged = [...document.querySelectorAll('#fingerprint-data span.hash')]
63            .map(e => [e.parentElement.textContent.trim().slice(0,12), e.className.replace('hash','').trim()])
64            .filter(([,c]) => c).map(([n,c]) => n+'='+c);
65        return 'stealth=' + pct('.stealth-rating') + ' headless=' + pct('.headless-rating')
66             + ' hashes=' + document.querySelectorAll('span.hash').length
67             + ' flagged=' + (flagged.join(',') || 'NONE');
68    })()"#;
69
70    match session.browser_mut().evaluate_script(expr, false).await {
71        Ok(v) => println!("\n=== CreepJS ===\n{:?}", v.result.value),
72        Err(e) => println!("\nevaluate failed: {e:?}"),
73    }
74
75    session.close().await;
76    Ok(())
77}