1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use bytes::Bytes;
use rand::distributions::DistString;
use rand::{distributions::Alphanumeric, Rng, RngCore};
use serde::{Deserialize, Serialize};

use crate::hex::encode_hex;

//系统版本
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OSVersion {
    pub incremental: String,
    pub release: String,
    pub codename: String,
    pub sdk: u32,
}

impl Default for OSVersion {
    fn default() -> Self {
        OSVersion {
            incremental: "5891938".into(),
            release: "10".into(),
            codename: "REL".into(),
            sdk: 29,
        }
    }
}

//手机设备信息
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
pub struct Device {
    pub display: String,
    pub product: String,
    pub device: String,
    pub board: String,
    pub model: String,
    pub finger_print: String,
    pub boot_id: String,
    pub proc_version: String,
    pub imei: String,
    pub brand: String,
    pub bootloader: String,
    pub base_band: String,
    pub version: OSVersion,
    pub sim_info: String,
    pub os_type: String,
    pub mac_address: String,
    pub ip_address: Vec<u8>,
    pub wifi_bssid: String,
    pub wifi_ssid: String,
    pub imsi_md5: Vec<u8>,
    pub android_id: String,
    pub apn: String,
    pub vendor_name: String,
    pub vendor_os_name: String,
}

impl Device {
    pub fn random() -> Self {
        Self::random_with_rng(&mut rand::thread_rng())
    }

    pub fn random_with_rng<RNG: RngCore>(rng: &mut RNG) -> Self {
        Self {
            display: format!("RICQ.{}.001", rng.gen_range(100000..999999)),
            product: "iarim".into(),
            device: "sagit".into(),
            board: "eomam".into(),
            model: "MI 6".into(),
            finger_print: format!(
                "xiaomi/iarim/sagit:10/eomam.200122.001/{}:user/release-keys",
                rng.gen_range(1000000..9999999)
            ),
            boot_id: random_uuid(rng),
            imei: random_imei(rng),
            proc_version: format!(
                "Linux 5.4.0-54-generic-{} (android-build@google.com)",
                Alphanumeric.sample_string(rng, 8)
            ),
            brand: "Xiaomi".into(),
            bootloader: "U-boot".into(),
            base_band: "".into(),
            version: OSVersion::default(),
            sim_info: "T-Mobile".into(),
            os_type: "android".into(),
            mac_address: "00:50:56:C0:00:08".into(),
            ip_address: vec![10, 0, 1, 3],
            wifi_bssid: "00:50:56:C0:00:08".into(),
            wifi_ssid: "<unknown ssid>".into(),
            imsi_md5: md5::compute(rng.gen::<[u8; 16]>()).to_vec(),
            android_id: encode_hex(&rng.gen::<[u8; 8]>()),
            apn: "wifi".into(),
            vendor_name: "MIUI".into(),
            vendor_os_name: "ricq".into(),
        }
    }

    pub fn ksid(&self) -> Bytes {
        Bytes::from(
            format!("|{}|A8.2.7.27f6ea96", self.imei)
                .as_bytes()
                .to_vec(),
        )
    }
}

pub fn random_string(len: usize) -> String {
    Alphanumeric.sample_string(&mut rand::thread_rng(), len)
}

pub fn random_uuid<RNG: RngCore>(rng: &mut RNG) -> String {
    let r = md5::compute(rng.gen::<[u8; 16]>()).to_vec();
    format!(
        "{}-{}-{}-{}-{}",
        encode_hex(&r[0..4]),
        encode_hex(&r[4..6]),
        encode_hex(&r[6..8]),
        encode_hex(&r[8..10]),
        encode_hex(&r[10..16])
    )
}

pub fn random_imei<RNG: RngCore>(rng: &mut RNG) -> String {
    let mut sum = 0;
    let mut str = String::new();
    for i in 0..14 {
        let mut to_add = rng.gen_range(0..10);
        if (i + 2) % 2 == 0 {
            to_add *= 2;
            if to_add >= 10 {
                to_add = (to_add % 10) + 1
            }
        }
        sum += to_add;
        str.push_str(&to_add.to_string());
    }
    let ctrl_digit = (sum * 9) % 10;
    str.push_str(&ctrl_digit.to_string());
    str
}