device-vipqvip 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
@@ -0,0 +1,2 @@
1
+ Run: py -3.12 -m pip install --upgrade build twine
2
+ Then: py -3.12 -m build
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.5
2
+ Name: device-vipqvip
3
+ Version: 0.1.1
4
+ Summary: Synthetic Android device profiles for testing and development
5
+ Author: device contributors
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+
15
+ # device
16
+
17
+ Synthetic Android device profiles for testing and development.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install device-vipqvip
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```python
28
+ import device
29
+
30
+ dev = device.generate_device()
31
+
32
+ print(dev["device"])
33
+ print(dev["android"])
34
+ print(dev["deviceName"])
35
+ print(dev["phoneModel"])
36
+ ```
37
+
38
+ Generate multiple profiles:
39
+
40
+ ```python
41
+ devices = device.generate_devices(10)
42
+ ```
43
+
44
+ Generate a profile for a requested brand:
45
+
46
+ ```python
47
+ dev = device.get_random_brand_device("samsung")
48
+ ```
49
+
50
+ The generated values are synthetic test data and should not be treated as
51
+ real device credentials or identifiers.
@@ -0,0 +1,37 @@
1
+ # device
2
+
3
+ Synthetic Android device profiles for testing and development.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install device-vipqvip
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ import device
15
+
16
+ dev = device.generate_device()
17
+
18
+ print(dev["device"])
19
+ print(dev["android"])
20
+ print(dev["deviceName"])
21
+ print(dev["phoneModel"])
22
+ ```
23
+
24
+ Generate multiple profiles:
25
+
26
+ ```python
27
+ devices = device.generate_devices(10)
28
+ ```
29
+
30
+ Generate a profile for a requested brand:
31
+
32
+ ```python
33
+ dev = device.get_random_brand_device("samsung")
34
+ ```
35
+
36
+ The generated values are synthetic test data and should not be treated as
37
+ real device credentials or identifiers.
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "device-vipqvip"
7
+ version = '0.1.1'
8
+ description = "Synthetic Android device profiles for testing and development"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "device contributors"}
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ ]
21
+
22
+ [tool.hatch.build.targets.wheel]
23
+ packages = ["src/device"]
@@ -0,0 +1,3 @@
1
+ from .generator import generate_device, generate_devices, get_random_brand_device, estimate_combinations
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,733 @@
1
+ # device_generator.py
2
+ # ══════════════════════════════════════════════════════════════
3
+ # مكتبة توليد هويات أجهزة أندرويد — لا نهاية للتوليد
4
+ # كل استدعاء = جهاز فريد 100% مختلف عن كل الأجهزة السابقة
5
+ # ══════════════════════════════════════════════════════════════
6
+
7
+ import random
8
+ import uuid
9
+ import string
10
+ import hashlib
11
+ import time
12
+
13
+ # ══════════════════════════════════════════════
14
+ # قواعد بيانات المصنّعين — حقيقية ومتكاملة
15
+ # ══════════════════════════════════════════════
16
+
17
+ # ─── Samsung ───────────────────────────────────
18
+ SAMSUNG = {
19
+ "brand": "samsung",
20
+ "manufacturer": "Samsung",
21
+ "series": [
22
+ # Galaxy S
23
+ {"prefix": "SM-S", "names": ["Galaxy S"], "numbers": list(range(20, 30)),
24
+ "suffixes": ["", "Ultra", "Plus", "FE", "+"],
25
+ "codes": ["B", "E", "U", "N", "W", "F", "G"]},
26
+ # Galaxy A
27
+ {"prefix": "SM-A", "names": ["Galaxy A"], "numbers": list(range(5, 100, 1)),
28
+ "suffixes": ["", "s", " 5G"],
29
+ "codes": ["F", "E", "B", "U", "N", "G", "FN", "BN"]},
30
+ # Galaxy M
31
+ {"prefix": "SM-M", "names": ["Galaxy M"], "numbers": list(range(10, 60, 5)),
32
+ "suffixes": ["", " 5G", "s"],
33
+ "codes": ["B", "F", "FN", "N"]},
34
+ # Galaxy F
35
+ {"prefix": "SM-F", "names": ["Galaxy F"], "numbers": list(range(12, 62, 2)),
36
+ "suffixes": ["", "s", " 5G"],
37
+ "codes": ["F", "B", "N"]},
38
+ # Galaxy Z
39
+ {"prefix": "SM-F", "names": ["Galaxy Z Fold", "Galaxy Z Flip"],
40
+ "numbers": list(range(3, 8)),
41
+ "suffixes": ["", " 5G"],
42
+ "codes": ["B", "W", "N", "U"]},
43
+ # Galaxy Tab
44
+ {"prefix": "SM-X", "names": ["Galaxy Tab S", "Galaxy Tab A"],
45
+ "numbers": list(range(5, 10)),
46
+ "suffixes": ["", " Ultra", " Plus", " FE"],
47
+ "codes": ["B", "F", "N", "U"]},
48
+ # Galaxy Note (legacy)
49
+ {"prefix": "SM-N", "names": ["Galaxy Note"],
50
+ "numbers": list(range(10, 21)),
51
+ "suffixes": ["", " Ultra", " Plus"],
52
+ "codes": ["B", "F", "N", "U", "W"]},
53
+ ],
54
+ "android_versions": [10, 11, 12, 13, 14],
55
+ "sdk_versions": [29, 30, 31, 32, 33, 34],
56
+ }
57
+
58
+ # ─── Xiaomi / Redmi / POCO ─────────────────────
59
+ XIAOMI = {
60
+ "brand": "Xiaomi",
61
+ "manufacturer": "Xiaomi",
62
+ "sub_brands": ["Xiaomi", "Redmi", "POCO"],
63
+ "models": {
64
+ "Xiaomi": {
65
+ "prefixes": ["2", "21", "22", "23"],
66
+ "series": ["Xiaomi ", "Mi "],
67
+ "numbers": list(range(10, 15)),
68
+ "suffixes": ["", " Pro", " Ultra", " Lite", "T", "T Pro"],
69
+ "len": [8, 9, 10],
70
+ },
71
+ "Redmi": {
72
+ "series": ["Redmi Note ", "Redmi ", "Redmi K"],
73
+ "numbers": list(range(9, 14)),
74
+ "suffixes": ["", " Pro", " Pro+", " Max", " Ultra", " 5G", "s"],
75
+ "prefixes": ["21", "22", "23", "M"],
76
+ "len": [8, 9, 10, 11],
77
+ },
78
+ "POCO": {
79
+ "series": ["POCO X", "POCO F", "POCO M", "POCO C"],
80
+ "numbers": list(range(3, 7)),
81
+ "suffixes": ["", " Pro", " GT", "s"],
82
+ "prefixes": ["22", "23", "21"],
83
+ "len": [8, 9, 10],
84
+ },
85
+ },
86
+ "android_versions": [11, 12, 13, 14],
87
+ "sdk_versions": [30, 31, 32, 33, 34],
88
+ }
89
+
90
+ # ─── OPPO ──────────────────────────────────────
91
+ OPPO = {
92
+ "brand": "OPPO",
93
+ "manufacturer": "OPPO",
94
+ "series": [
95
+ {"prefix": "CPH", "start": 2100, "end": 2600,
96
+ "names": ["OPPO Find X", "OPPO Reno", "OPPO A", "OPPO F"],
97
+ "numbers": list(range(3, 12)),
98
+ "suffixes": ["", " Pro", " Plus", " 5G", " Ultra"]},
99
+ {"prefix": "PERM", "start": 0, "end": 99,
100
+ "names": ["OPPO Find N"],
101
+ "numbers": list(range(2, 5)),
102
+ "suffixes": ["", " Pro", " Flip"]},
103
+ ],
104
+ "android_versions": [11, 12, 13, 14],
105
+ "sdk_versions": [30, 31, 32, 33, 34],
106
+ }
107
+
108
+ # ─── Realme ────────────────────────────────────
109
+ REALME = {
110
+ "brand": "realme",
111
+ "manufacturer": "realme",
112
+ "series": [
113
+ {"prefix": "RMX", "start": 3000, "end": 3900,
114
+ "names": ["Realme GT", "Realme ", "Realme C", "Realme Narzo"],
115
+ "numbers": list(range(2, 13)),
116
+ "suffixes": ["", " Pro", " Pro+", " Neo", " Master Edition", " 5G"]},
117
+ ],
118
+ "android_versions": [11, 12, 13, 14],
119
+ "sdk_versions": [30, 31, 32, 33, 34],
120
+ }
121
+
122
+ # ─── Vivo ──────────────────────────────────────
123
+ VIVO = {
124
+ "brand": "vivo",
125
+ "manufacturer": "vivo",
126
+ "series": [
127
+ {"prefix": "V", "start": 21, "end": 30,
128
+ "names": ["vivo V", "vivo Y", "vivo T", "vivo iQOO"],
129
+ "numbers": list(range(20, 31)),
130
+ "suffixes": ["", " Pro", "e", "s", " 5G", "t"]},
131
+ {"prefix": "PD", "start": 2000, "end": 2400,
132
+ "names": ["vivo X", "vivo iQOO"],
133
+ "numbers": list(range(70, 100)),
134
+ "suffixes": ["", " Pro", " Ultra", " Mini"]},
135
+ ],
136
+ "android_versions": [11, 12, 13, 14],
137
+ "sdk_versions": [30, 31, 32, 33, 34],
138
+ }
139
+
140
+ # ─── OnePlus ───────────────────────────────────
141
+ ONEPLUS = {
142
+ "brand": "OnePlus",
143
+ "manufacturer": "OnePlus",
144
+ "series": [
145
+ {"prefix": "CPH", "start": 2400, "end": 2600,
146
+ "names": ["OnePlus "],
147
+ "numbers": list(range(9, 14)),
148
+ "suffixes": ["", " Pro", " R", " Nord", " Nord CE", " Nord N"]},
149
+ {"prefix": "IN", "start": 2010, "end": 2023,
150
+ "names": ["OnePlus Nord"],
151
+ "numbers": list(range(2, 5)),
152
+ "suffixes": ["", " CE 3", " CE 2", " Lite"]},
153
+ ],
154
+ "android_versions": [11, 12, 13, 14],
155
+ "sdk_versions": [30, 31, 32, 33, 34],
156
+ }
157
+
158
+ # ─── Huawei ────────────────────────────────────
159
+ HUAWEI = {
160
+ "brand": "HUAWEI",
161
+ "manufacturer": "HUAWEI",
162
+ "series": [
163
+ {"codes": ["NOH", "NCO", "ALN", "VNE", "RTE", "DCO", "FNE"],
164
+ "suffixes_code": ["-AL00", "-NX9", "-LX1", "-AN00", "-TN00"],
165
+ "names": ["HUAWEI P", "HUAWEI Mate", "HUAWEI nova"],
166
+ "numbers": list(range(50, 70)),
167
+ "suffixes": ["", " Pro", " Ultra", " Art", " RS"]},
168
+ ],
169
+ "android_versions": [10, 11, 12],
170
+ "sdk_versions": [29, 30, 31],
171
+ }
172
+
173
+ # ─── Honor ─────────────────────────────────────
174
+ HONOR = {
175
+ "brand": "Honor",
176
+ "manufacturer": "HONOR",
177
+ "series": [
178
+ {"codes": ["REA", "ANY", "CRT", "FNE", "RKY", "WFQ"],
179
+ "suffixes_code": ["-NX9", "-LX1", "-LX2", "-AN00"],
180
+ "names": ["Honor ", "Honor X", "Honor Magic"],
181
+ "numbers": list(range(50, 100)),
182
+ "x_numbers": list(range(5, 12)),
183
+ "suffixes": ["", "a", " Pro", " Lite", " 5G"]},
184
+ ],
185
+ "android_versions": [11, 12, 13, 14],
186
+ "sdk_versions": [30, 31, 32, 33, 34],
187
+ }
188
+
189
+ # ─── Infinix ───────────────────────────────────
190
+ INFINIX = {
191
+ "brand": "Infinix",
192
+ "manufacturer": "Infinix",
193
+ "models_prefix": ["X", "XP"],
194
+ "series": ["Infinix Note ", "Infinix Hot ", "Infinix Zero ",
195
+ "Infinix Smart ", "Infinix GT "],
196
+ "numbers": list(range(10, 42)),
197
+ "suffixes": ["", " Pro", " Pro+", " Ultra", " NFC", " 5G"],
198
+ "model_range": list(range(6500, 6900)),
199
+ "android_versions": [11, 12, 13],
200
+ "sdk_versions": [30, 31, 32, 33],
201
+ }
202
+
203
+ # ─── Tecno ─────────────────────────────────────
204
+ TECNO = {
205
+ "brand": "TECNO",
206
+ "manufacturer": "TECNO",
207
+ "series": ["Tecno Camon ", "Tecno Spark ", "Tecno Pova ",
208
+ "Tecno Pop ", "Tecno Phantom "],
209
+ "numbers": list(range(10, 25)),
210
+ "suffixes": ["", " Pro", " 5G", " NFC", " Ultra"],
211
+ "model_codes": list("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
212
+ "model_nums": list(range(1, 20)),
213
+ "android_versions": [11, 12, 13],
214
+ "sdk_versions": [30, 31, 32, 33],
215
+ }
216
+
217
+ # ─── Motorola ──────────────────────────────────
218
+ MOTOROLA = {
219
+ "brand": "motorola",
220
+ "manufacturer": "motorola",
221
+ "series": [
222
+ {"prefix": "moto g", "numbers": list(range(20, 85, 5)),
223
+ "suffixes": ["", " power", " play", " stylus", " 5G", " plus"]},
224
+ {"prefix": "moto e", "numbers": list(range(20, 50, 5)),
225
+ "suffixes": ["", " fusion", " plus"]},
226
+ {"prefix": "edge ", "numbers": list(range(20, 50, 5)),
227
+ "suffixes": ["", "+", " pro", " ultra"]},
228
+ {"prefix": "razr", "numbers": list(range(2020, 2024)),
229
+ "suffixes": ["", "+", " 5G"]},
230
+ ],
231
+ "model_prefix": ["XT", "MZ"],
232
+ "model_range": list(range(1900, 2400)),
233
+ "android_versions": [11, 12, 13, 14],
234
+ "sdk_versions": [30, 31, 32, 33, 34],
235
+ }
236
+
237
+ # ─── Nokia ─────────────────────────────────────
238
+ NOKIA = {
239
+ "brand": "Nokia",
240
+ "manufacturer": "HMD Global",
241
+ "series": ["Nokia ", "Nokia G", "Nokia C", "Nokia X"],
242
+ "numbers": list(range(1, 50)),
243
+ "suffixes": ["", " Plus", " 5G", " 4G"],
244
+ "model_format": ["TA-{}", "NKN-{}", "TA-{:04d}"],
245
+ "model_range": list(range(1000, 2200)),
246
+ "android_versions": [11, 12, 13],
247
+ "sdk_versions": [30, 31, 32, 33],
248
+ }
249
+
250
+ # ─── Sony ──────────────────────────────────────
251
+ SONY = {
252
+ "brand": "Sony",
253
+ "manufacturer": "Sony",
254
+ "series": ["Xperia 1", "Xperia 5", "Xperia 10"],
255
+ "gen_prefix": ["XQ-", "SO-", "SOV"],
256
+ "gen_codes": list("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
257
+ "gen_nums": list(range(10, 99)),
258
+ "generations": list(range(3, 7)),
259
+ "suffixes": ["", " III", " IV", " V", " VI"],
260
+ "android_versions": [12, 13, 14],
261
+ "sdk_versions": [31, 32, 33, 34],
262
+ }
263
+
264
+ # ─── Asus ──────────────────────────────────────
265
+ ASUS = {
266
+ "brand": "asus",
267
+ "manufacturer": "asus",
268
+ "series": [
269
+ {"prefix": "ASUS_", "names": ["ASUS ROG Phone ", "Zenfone "],
270
+ "numbers": list(range(5, 12)),
271
+ "suffixes": ["", " Pro", " Ultimate", " s", " Pro Model"]},
272
+ ],
273
+ "model_nums": list(range(1000, 9999)),
274
+ "android_versions": [12, 13, 14],
275
+ "sdk_versions": [31, 32, 33, 34],
276
+ }
277
+
278
+ # ─── Google Pixel ──────────────────────────────
279
+ GOOGLE = {
280
+ "brand": "google",
281
+ "manufacturer": "Google",
282
+ "series": ["Pixel "],
283
+ "numbers": list(range(4, 9)),
284
+ "suffixes": ["", " a", " XL", " Pro", " Fold"],
285
+ "model_prefix": ["GP4", "GP5", "GP6", "GP7", "GP8", "GE2AE", "GP8C"],
286
+ "model_suffix": ["A", "B", "C"],
287
+ "android_versions": [12, 13, 14, 15],
288
+ "sdk_versions": [31, 32, 33, 34, 35],
289
+ }
290
+
291
+ # ─── LG (legacy) ───────────────────────────────
292
+ LG = {
293
+ "brand": "lge",
294
+ "manufacturer": "LGE",
295
+ "series": ["LG V", "LG G", "LG Velvet", "LG Wing", "LG K"],
296
+ "numbers": list(range(40, 70)),
297
+ "model_prefix": ["LM-"],
298
+ "model_codes": ["V", "G", "K", "Q", "X"],
299
+ "model_nums": list(range(400, 700)),
300
+ "android_versions": [10, 11, 12],
301
+ "sdk_versions": [29, 30, 31],
302
+ }
303
+
304
+ # ─── ZTE ───────────────────────────────────────
305
+ ZTE = {
306
+ "brand": "ZTE",
307
+ "manufacturer": "ZTE",
308
+ "series": ["ZTE Blade ", "ZTE Axon ", "ZTE nubia Z", "ZTE nubia Red Magic "],
309
+ "numbers": list(range(10, 50)),
310
+ "suffixes": ["", " Pro", " Plus", " Max", " 5G"],
311
+ "model_prefix": ["ZTE ", "A"],
312
+ "model_nums": list(range(1000, 3000)),
313
+ "android_versions": [11, 12, 13],
314
+ "sdk_versions": [30, 31, 32, 33],
315
+ }
316
+
317
+ # جمع كل المصنّعين
318
+ ALL_BRANDS = [
319
+ SAMSUNG, XIAOMI, OPPO, REALME, VIVO,
320
+ ONEPLUS, HUAWEI, HONOR, INFINIX, TECNO,
321
+ MOTOROLA, NOKIA, SONY, ASUS, GOOGLE, LG, ZTE
322
+ ]
323
+
324
+ # ══════════════════════════════════════════════
325
+ # مولّدات النماذج
326
+ # ══════════════════════════════════════════════
327
+
328
+ def _rand_str(n, chars=string.ascii_uppercase + string.digits):
329
+ return ''.join(random.choices(chars, k=n))
330
+
331
+ def _gen_samsung():
332
+ s = random.choice(SAMSUNG["series"])
333
+ name_base = random.choice(s["names"])
334
+ num = random.choice(s["numbers"])
335
+ suffix = random.choice(s["suffixes"])
336
+ code = random.choice(s["codes"])
337
+ # model code digits
338
+ digits = str(num).zfill(2) + str(random.randint(0,9))
339
+ model = f"{s['prefix']}{digits}{code}"
340
+ name = f"{name_base}{num}{(' ' + suffix) if suffix else ''}"
341
+ return name.strip(), model
342
+
343
+ def _gen_xiaomi():
344
+ sub = random.choice(XIAOMI["sub_brands"])
345
+ cfg = XIAOMI["models"][sub]
346
+ series = random.choice(cfg["series"])
347
+ num = random.choice(cfg["numbers"])
348
+ suffix = random.choice(cfg["suffixes"])
349
+ # generate model code
350
+ length = random.choice(cfg["len"])
351
+ prefix = random.choice(cfg["prefixes"])
352
+ mid = ''.join(random.choices(string.digits, k=length - len(prefix)))
353
+ suffix_code = random.choice(list("ABCGINU"))
354
+ model = prefix + mid + suffix_code
355
+ name = f"{series}{num}{suffix}".strip()
356
+ return name, model
357
+
358
+ def _gen_oppo():
359
+ s = random.choice(OPPO["series"])
360
+ name_base = random.choice(s["names"])
361
+ num = random.choice(s["numbers"])
362
+ suffix = random.choice(s["suffixes"])
363
+ model_num = random.randint(s["start"], s["end"])
364
+ model = f"{s['prefix']}{model_num}"
365
+ name = f"{name_base}{num}{suffix}".strip()
366
+ return name, model
367
+
368
+ def _gen_realme():
369
+ s = random.choice(REALME["series"])
370
+ name_base = random.choice(s["names"])
371
+ num = random.choice(s["numbers"])
372
+ suffix = random.choice(s["suffixes"])
373
+ model_num = random.randint(s["start"], s["end"])
374
+ model = f"{s['prefix']}{model_num}"
375
+ name = f"{name_base}{num}{suffix}".strip()
376
+ return name, model
377
+
378
+ def _gen_vivo():
379
+ s = random.choice(VIVO["series"])
380
+ name_base = random.choice(s["names"])
381
+ num = random.choice(s["numbers"])
382
+ suffix = random.choice(s["suffixes"])
383
+ model_num = random.randint(s["start"], s["end"])
384
+ model = f"{s['prefix']}{model_num}"
385
+ name = f"{name_base}{num}{suffix}".strip()
386
+ return name, model
387
+
388
+ def _gen_oneplus():
389
+ s = random.choice(ONEPLUS["series"])
390
+ name_base = random.choice(s["names"])
391
+ num = random.choice(s["numbers"])
392
+ suffix = random.choice(s["suffixes"])
393
+ model_num = random.randint(s["start"], s["end"])
394
+ model = f"{s['prefix']}{model_num}"
395
+ name = f"{name_base}{num}{suffix}".strip()
396
+ return name, model
397
+
398
+ def _gen_huawei():
399
+ s = HUAWEI["series"][0]
400
+ code = random.choice(s["codes"])
401
+ sfx = random.choice(s["suffixes_code"])
402
+ model = f"{code}{sfx}"
403
+ name_base = random.choice(s["names"])
404
+ num = random.choice(s["numbers"])
405
+ suffix = random.choice(s["suffixes"])
406
+ name = f"{name_base}{num}{suffix}".strip()
407
+ return name, model
408
+
409
+ def _gen_honor():
410
+ s = HONOR["series"][0]
411
+ code = random.choice(s["codes"])
412
+ sfx = random.choice(s["suffixes_code"])
413
+ model = f"{code}{sfx}"
414
+ name_base = random.choice(s["names"])
415
+ if "X" in name_base:
416
+ num = random.choice(s["x_numbers"])
417
+ else:
418
+ num = random.choice(s["numbers"])
419
+ suffix = random.choice(s["suffixes"])
420
+ name = f"{name_base}{num}{suffix}".strip()
421
+ return name, model
422
+
423
+ def _gen_infinix():
424
+ cfg = INFINIX
425
+ series = random.choice(cfg["series"])
426
+ num = random.choice(cfg["numbers"])
427
+ suffix = random.choice(cfg["suffixes"])
428
+ model_prefix = random.choice(cfg["models_prefix"])
429
+ model_num = random.choice(cfg["model_range"])
430
+ model = f"{model_prefix}{model_num}"
431
+ name = f"{series}{num}{suffix}".strip()
432
+ return name, model
433
+
434
+ def _gen_tecno():
435
+ cfg = TECNO
436
+ series = random.choice(cfg["series"])
437
+ num = random.choice(cfg["numbers"])
438
+ suffix = random.choice(cfg["suffixes"])
439
+ mc = random.choice(cfg["model_codes"])
440
+ mn = random.choice(cfg["model_nums"])
441
+ model = f"{mc}{mn}"
442
+ name = f"{series}{num}{suffix}".strip()
443
+ return name, model
444
+
445
+ def _gen_motorola():
446
+ s = random.choice(MOTOROLA["series"])
447
+ num = random.choice(s["numbers"])
448
+ suffix = random.choice(s["suffixes"])
449
+ model_p = random.choice(MOTOROLA["model_prefix"])
450
+ model_n = random.choice(MOTOROLA["model_range"])
451
+ model = f"{model_p}{model_n}"
452
+ name = f"{s['prefix']}{num}{suffix}".strip()
453
+ return name, model
454
+
455
+ def _gen_nokia():
456
+ cfg = NOKIA
457
+ series = random.choice(cfg["series"])
458
+ num = random.choice(cfg["numbers"])
459
+ suffix = random.choice(cfg["suffixes"])
460
+ fmt = random.choice(cfg["model_format"])
461
+ mn = random.choice(cfg["model_range"])
462
+ try: model = fmt.format(mn)
463
+ except: model = f"TA-{mn}"
464
+ name = f"{series}{num}{suffix}".strip()
465
+ return name, model
466
+
467
+ def _gen_sony():
468
+ cfg = SONY
469
+ series = random.choice(cfg["series"])
470
+ gen = random.choice(cfg["generations"])
471
+ suffix = random.choice(cfg["suffixes"])
472
+ pre = random.choice(cfg["gen_prefix"])
473
+ c1 = random.choice(cfg["gen_codes"])
474
+ c2 = random.choice(cfg["gen_codes"])
475
+ n = random.choice(cfg["gen_nums"])
476
+ model = f"{pre}{c1}{c2}{n}"
477
+ name = f"{series} {gen}{suffix}".strip()
478
+ return name, model
479
+
480
+ def _gen_asus():
481
+ cfg = ASUS
482
+ s = random.choice(cfg["series"])
483
+ name_base = random.choice(s["names"])
484
+ num = random.choice(s["numbers"])
485
+ suffix = random.choice(s["suffixes"])
486
+ mn = random.choice(cfg["model_nums"])
487
+ model = f"{s['prefix']}{mn}"
488
+ name = f"{name_base}{num}{suffix}".strip()
489
+ return name, model
490
+
491
+ def _gen_google():
492
+ cfg = GOOGLE
493
+ series = random.choice(cfg["series"])
494
+ num = random.choice(cfg["numbers"])
495
+ suffix = random.choice(cfg["suffixes"])
496
+ pre = random.choice(cfg["model_prefix"])
497
+ sfx = random.choice(cfg["model_suffix"])
498
+ model = f"{pre}{sfx}"
499
+ name = f"{series}{num}{suffix}".strip()
500
+ return name, model
501
+
502
+ def _gen_lg():
503
+ cfg = LG
504
+ series = random.choice(cfg["series"])
505
+ num = random.choice(cfg["numbers"])
506
+ pre = random.choice(cfg["model_prefix"])
507
+ mc = random.choice(cfg["model_codes"])
508
+ mn = random.choice(cfg["model_nums"])
509
+ model = f"{pre}{mc}{mn}"
510
+ name = f"{series}{num}".strip()
511
+ return name, model
512
+
513
+ def _gen_zte():
514
+ cfg = ZTE
515
+ series = random.choice(cfg["series"])
516
+ num = random.choice(cfg["numbers"])
517
+ suffix = random.choice(cfg["suffixes"])
518
+ pre = random.choice(cfg["model_prefix"])
519
+ mn = random.choice(cfg["model_nums"])
520
+ model = f"{pre}{mn}"
521
+ name = f"{series}{num}{suffix}".strip()
522
+ return name, model
523
+
524
+ # ── جدول الدوال ──
525
+ BRAND_GENERATORS = [
526
+ _gen_samsung, _gen_xiaomi, _gen_oppo, _gen_realme,
527
+ _gen_vivo, _gen_oneplus, _gen_huawei, _gen_honor,
528
+ _gen_infinix, _gen_tecno, _gen_motorola, _gen_nokia,
529
+ _gen_sony, _gen_asus, _gen_google, _gen_lg, _gen_zte,
530
+ ]
531
+
532
+ # أوزان — كثرة انتشار كل ماركة في المنطقة العربية
533
+ BRAND_WEIGHTS = [
534
+ 25, # Samsung — الأكثر
535
+ 20, # Xiaomi
536
+ 10, # OPPO
537
+ 8, # Realme
538
+ 5, # Vivo
539
+ 4, # OnePlus
540
+ 4, # Huawei
541
+ 4, # Honor
542
+ 6, # Infinix
543
+ 5, # Tecno
544
+ 2, # Motorola
545
+ 1, # Nokia
546
+ 1, # Sony
547
+ 1, # Asus
548
+ 1, # Google
549
+ 1, # LG
550
+ 1, # ZTE
551
+ ]
552
+
553
+ # ══════════════════════════════════════════════
554
+ # Android IDs & Device IDs
555
+ # ══════════════════════════════════════════════
556
+
557
+ def _gen_android_id():
558
+ """Android ID — 16 حرف hex"""
559
+ return ''.join(random.choices('0123456789abcdef', k=16))
560
+
561
+ def _gen_device_uuid():
562
+ """Device UUID — الصيغة الكاملة"""
563
+ return str(uuid.uuid4())
564
+
565
+ def _gen_shumeng_id(length=36):
566
+ """ShuMeng ID — alphanumeric"""
567
+ chars = string.ascii_letters + string.digits
568
+ return ''.join(random.choices(chars, k=length))
569
+
570
+ def _gen_imei():
571
+ """IMEI وهمي صحيح الصيغة"""
572
+ tac = random.choice([
573
+ "35674", "35812", "35937", "86732",
574
+ "86891", "35246", "86423", "35781",
575
+ "35409", "86512", "35678", "86345",
576
+ ])
577
+ snr = ''.join(random.choices(string.digits, k=6))
578
+ partial = tac + snr
579
+ # Luhn check digit
580
+ total = 0
581
+ for i, d in enumerate(partial):
582
+ n = int(d)
583
+ if i % 2 == 1:
584
+ n *= 2
585
+ if n > 9: n -= 9
586
+ total += n
587
+ check = (10 - (total % 10)) % 10
588
+ return partial + str(check)
589
+
590
+ def _gen_mac():
591
+ """MAC address"""
592
+ return ':'.join(f'{random.randint(0,255):02X}' for _ in range(6))
593
+
594
+ def _gen_serial():
595
+ """Serial number"""
596
+ chars = string.ascii_uppercase + string.digits
597
+ return ''.join(random.choices(chars, k=random.randint(8, 12)))
598
+
599
+ # ══════════════════════════════════════════════
600
+ # الدالة الرئيسية — توليد هوية كاملة
601
+ # ══════════════════════════════════════════════
602
+
603
+ def generate_device() -> dict:
604
+ """
605
+ توليد هوية جهاز أندرويد كاملة وفريدة.
606
+
607
+ الإرجاع:
608
+ dict يحتوي على كل بيانات الجهاز
609
+
610
+ مثال:
611
+ dev = generate_device()
612
+ print(dev['deviceName']) # Samsung Galaxy S23 Ultra
613
+ print(dev['phoneModel']) # SM-S918B
614
+ print(dev['device']) # uuid
615
+ print(dev['android']) # android_id_suffix
616
+ """
617
+ # اختيار المولّد حسب الوزن
618
+ gen_fn = random.choices(BRAND_GENERATORS, weights=BRAND_WEIGHTS, k=1)[0]
619
+
620
+ try:
621
+ device_name, phone_model = gen_fn()
622
+ except Exception:
623
+ # fallback آمن
624
+ device_name, phone_model = _gen_samsung()
625
+
626
+ # تحديد إصدار Android بناءً على المصنّع
627
+ # (نحصل على الإصدار من قاموس المصنّع المناسب)
628
+ android_v = random.choice([10, 11, 12, 13, 14])
629
+ sdk_v = {10:29, 11:30, 12:31, 13:33, 14:34}.get(android_v, 31)
630
+
631
+ device_uuid = _gen_device_uuid()
632
+ android_id = _gen_android_id()
633
+
634
+ return {
635
+ # ── الحقول التي يستخدمها الكود مباشرة ──
636
+ "device": device_uuid,
637
+ "android": f"{android_id}_{uuid.uuid4().hex[:16]}",
638
+ "shumeng": _gen_shumeng_id(36),
639
+ "deviceName": device_name,
640
+ "phoneModel": phone_model,
641
+
642
+ # ── معلومات إضافية (للتوسع) ──
643
+ "brand": device_name.split()[0] if device_name else "Samsung",
644
+ "androidVersion": str(android_v),
645
+ "sdkVersion": str(sdk_v),
646
+ "imei": _gen_imei(),
647
+ "mac": _gen_mac(),
648
+ "serial": _gen_serial(),
649
+ "deviceUUID": device_uuid,
650
+ "androidId": android_id,
651
+ }
652
+
653
+ # ══════════════════════════════════════════════
654
+ # API مساعد
655
+ # ══════════════════════════════════════════════
656
+
657
+ def generate_devices(count: int) -> list:
658
+ """توليد عدد محدد من الأجهزة"""
659
+ return [generate_device() for _ in range(count)]
660
+
661
+ def get_random_brand_device(brand: str) -> dict:
662
+ """
663
+ طلب جهاز من ماركة محددة.
664
+ brand: 'samsung' | 'xiaomi' | 'oppo' | 'realme' | ...
665
+ """
666
+ brand_map = {
667
+ 'samsung': _gen_samsung,
668
+ 'xiaomi': _gen_xiaomi,
669
+ 'redmi': _gen_xiaomi,
670
+ 'poco': _gen_xiaomi,
671
+ 'oppo': _gen_oppo,
672
+ 'realme': _gen_realme,
673
+ 'vivo': _gen_vivo,
674
+ 'oneplus': _gen_oneplus,
675
+ 'huawei': _gen_huawei,
676
+ 'honor': _gen_honor,
677
+ 'infinix': _gen_infinix,
678
+ 'tecno': _gen_tecno,
679
+ 'motorola': _gen_motorola,
680
+ 'nokia': _gen_nokia,
681
+ 'sony': _gen_sony,
682
+ 'asus': _gen_asus,
683
+ 'google': _gen_google,
684
+ 'pixel': _gen_google,
685
+ 'lg': _gen_lg,
686
+ 'zte': _gen_zte,
687
+ }
688
+ fn = brand_map.get(brand.lower(), generate_device)
689
+ try:
690
+ device_name, phone_model = fn()
691
+ except:
692
+ device_name, phone_model = _gen_samsung()
693
+
694
+ device_uuid = _gen_device_uuid()
695
+ android_id = _gen_android_id()
696
+ return {
697
+ "device": device_uuid,
698
+ "android": f"{android_id}_{uuid.uuid4().hex[:16]}",
699
+ "shumeng": _gen_shumeng_id(36),
700
+ "deviceName": device_name,
701
+ "phoneModel": phone_model,
702
+ "androidId": android_id,
703
+ "imei": _gen_imei(),
704
+ "mac": _gen_mac(),
705
+ "serial": _gen_serial(),
706
+ }
707
+
708
+ def estimate_combinations() -> int:
709
+ """تقدير عدد التوليفات الممكنة"""
710
+ # Samsung alone: 7 series × 10 numbers × 6 suffixes × 7 codes = 2940
711
+ # Xiaomi: 3 brands × 4 series × 10 nums × 6 suffixes × huge model codes
712
+ # UUID: 2^122 ≈ 5.3 × 10^36
713
+ # AndroidId: 16^16 ≈ 1.8 × 10^19
714
+ # Combined: practically unlimited
715
+ return 10**36 # > 1 سكستيليون
716
+
717
+ # ══════════════════════════════════════════════
718
+ # اختبار
719
+ # ══════════════════════════════════════════════
720
+ if __name__ == "__main__":
721
+ print("🔬 Device Generator — اختبار\n")
722
+ print(f"📊 التوليفات المقدّرة: {estimate_combinations():,}\n")
723
+
724
+ print("─" * 55)
725
+ print(f"{'Device Name':<35} {'Model':<15}")
726
+ print("─" * 55)
727
+
728
+ for i in range(20):
729
+ dev = generate_device()
730
+ print(f"{dev['deviceName']:<35} {dev['phoneModel']:<15}")
731
+
732
+ print("─" * 55)
733
+ print(f"\n✅ كل جهاز فريد 100% بسبب UUID + AndroidID العشوائي")