false, 'error' => 'Missing required parameter: serial', ]; } // Mini-VID-Datenbank (kannst du später aus Datei/DB laden) $VID_DB = [ '0781' => 'SanDisk Corp.', '0951' => 'Kingston Technology', '054C' => 'Sony Corp.', '1B1C' => 'Corsair', '13FE' => 'Phison Electronics', '8564' => 'Transcend Information, Inc.', '090C' => 'Silicon Motion, Inc.', '174C' => 'ASMedia Technology', '0BC2' => 'Seagate', // ... nach Bedarf ergänzen ]; $vendorInfo = quickcheck_lookup_vendor($vid, $VID_DB); $serialAnalysis = quickcheck_analyze_serial($serial); $consistencyInfo = quickcheck_evaluate_consistency($vendorInfo['vendor'] ?? null, $manufacturer, $serialAnalysis); // Gesamtrating $rating = 'ok'; if ($serialAnalysis['category'] === 'invalid') { $rating = 'invalid'; } elseif ($serialAnalysis['category'] === 'very_suspicious' || $consistencyInfo['manufacturer_match'] === 'mismatch') { $rating = 'suspicious'; } elseif ($serialAnalysis['category'] === 'suspicious') { $rating = 'needs_review'; } return [ 'success' => true, 'rating' => $rating, 'input' => [ 'vid' => $vid, 'pid' => $pid, 'manufacturer' => $manufacturer, 'serial' => $serial, ], 'vendor_detected' => $vendorInfo, 'serial_analysis' => $serialAnalysis, 'consistency' => $consistencyInfo, 'messages' => [ 'de' => [ 'Hinweis: Diese Prüfung kann keine Echtheit garantieren, sondern bewertet nur Plausibilität und Auffälligkeiten.', ], ], ]; } /** * Eingaben lesen: JSON-Body > POST > GET */ function quickcheck_get_input(): array { $contentType = $_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? ''; $contentType = strtolower(trim(explode(';', $contentType)[0])); if ($contentType === 'application/json') { $raw = file_get_contents('php://input'); if ($raw !== false && $raw !== '') { $data = json_decode($raw, true); if (json_last_error() === JSON_ERROR_NONE && is_array($data)) { return $data; } } } if (!empty($_POST)) { return $_POST; } if (!empty($_GET)) { return $_GET; } return []; } /** * VID normalisieren + Lookup */ function quickcheck_normalize_vid(string $vid): ?string { $vid = strtoupper(trim($vid)); $vid = preg_replace('/^0X/i', '', $vid); if ($vid === '' || !preg_match('/^[0-9A-F]{1,4}$/', $vid)) { return null; } return str_pad($vid, 4, '0', STR_PAD_LEFT); } function quickcheck_lookup_vendor(?string $vid, array $VID_DB): array { if (!$vid) { return [ 'vid' => null, 'found' => false, 'vendor' => null, 'confidence' => 0, ]; } $norm = quickcheck_normalize_vid($vid); if (!$norm) { return [ 'vid' => $vid, 'found' => false, 'vendor' => null, 'confidence' => 0, 'issue' => 'Invalid VID format', ]; } if (isset($VID_DB[$norm])) { return [ 'vid' => $norm, 'found' => true, 'vendor' => $VID_DB[$norm], 'confidence' => 1.0, ]; } return [ 'vid' => $norm, 'found' => false, 'vendor' => null, 'confidence' => 0.2, ]; } /** * Seriennummer grob analysieren (Plausibilität) */ function quickcheck_analyze_serial(string $serial): array { $serial = trim($serial); $length = strlen($serial); $issues = []; $score = 100; if ($length === 0) { return [ 'serial' => $serial, 'length' => 0, 'issues' => ['empty'], 'score' => 0, 'category' => 'invalid', ]; } if ($length < 4) { $issues[] = 'too_short_critical'; $score -= 60; } elseif ($length < 8) { $issues[] = 'short_suspicious'; $score -= 30; } if ($length > 32) { $issues[] = 'very_long'; $score -= 10; } if (quickcheck_is_all_same_char($serial)) { $issues[] = 'all_same_char'; $score -= 50; } $simplePatterns = [ '000000', '00000000', '000000000000', '111111', '123456', '12345678', 'ABCDEF', 'AABBCC' ]; if (in_array(strtoupper($serial), $simplePatterns, true)) { $issues[] = 'simple_pattern'; $score -= 40; } if (quickcheck_is_simple_sequence($serial)) { $issues[] = 'sequence_pattern'; $score -= 25; } $isNumeric = preg_match('/^[0-9]+$/', $serial) === 1; $isAlpha = preg_match('/^[A-Za-z]+$/', $serial) === 1; $isHex = preg_match('/^[0-9A-Fa-f]+$/', $serial) === 1; $isAlnum = preg_match('/^[A-Za-z0-9]+$/', $serial) === 1; if ($isNumeric) { $issues[] = 'numeric_only'; $score -= 10; } elseif ($isAlpha) { $issues[] = 'letters_only'; $score -= 10; } if ($isHex && !$isNumeric && $length >= 8 && $length <= 24) { $issues[] = 'hex_pattern_plausible'; $score += 5; } if ($isAlnum && !$isNumeric && !$isAlpha && $length >= 8) { $issues[] = 'alnum_mixed_plausible'; $score += 5; } if ($score > 100) $score = 100; if ($score < 0) $score = 0; if ($length === 0) { $category = 'invalid'; } elseif ($score >= 80) { $category = 'plausible'; } elseif ($score >= 50) { $category = 'suspicious'; } else { $category = 'very_suspicious'; } return [ 'serial' => $serial, 'length' => $length, 'issues' => array_values(array_unique($issues)), 'score' => $score, 'category' => $category, ]; } function quickcheck_is_all_same_char(string $s): bool { return strlen($s) > 1 && preg_match('/^(.)\1+$/', $s) === 1; } function quickcheck_is_simple_sequence(string $s): bool { $seqs = [ '123456', '1234567', '12345678', '234567', '345678', 'ABCDEFG', 'ABCDEF', 'ABCDE' ]; $ls = strtoupper($s); foreach ($seqs as $pattern) { if (strpos($ls, $ls) !== false && strpos($ls, $pattern) !== false) { return true; } } return false; } /** * Herstellerangabe vs. Vendor-Name bewerten */ function quickcheck_evaluate_consistency(?string $vendorName, string $userManufacturer, array $serialAnalysis): array { $vendorName = $vendorName ? trim($vendorName) : ''; $userManufacturer = trim($userManufacturer); $matchStatus = 'unknown'; $notes = []; if ($vendorName !== '' && $userManufacturer !== '') { $v = mb_strtolower($vendorName); $u = mb_strtolower($userManufacturer); if (strpos($v, $u) !== false || strpos($u, $v) !== false) { $matchStatus = 'match'; $notes[] = 'Herstellerangabe passt zur ermittelten Vendor-ID.'; } else { $matchStatus = 'mismatch'; $notes[] = 'Herstellerangabe weicht von der Vendor-ID ab.'; } } elseif ($vendorName !== '') { $notes[] = 'Hersteller über Vendor-ID bekannt, aber keine Herstellerangabe des Nutzers.'; } elseif ($userManufacturer !== '') { $notes[] = 'Hersteller vom Nutzer angegeben, aber keine oder unbekannte Vendor-ID.'; } else { $notes[] = 'Keine Herstellerinformationen vorhanden.'; } $ratingHint = 'neutral'; if ($serialAnalysis['category'] === 'very_suspicious' || $matchStatus === 'mismatch') { $ratingHint = 'suspicious'; } elseif ($serialAnalysis['category'] === 'plausible' && $matchStatus === 'match') { $ratingHint = 'good'; } return [ 'manufacturer_match' => $matchStatus, 'notes' => $notes, 'consistency_hint' => $ratingHint, ]; }