PDO::ERRMODE_EXCEPTION] ); // Deteksi apakah sudah dimasking: cek apakah M_PatientName masih plaintext // (plaintext = tidak ada '***', sudah masked = ada '***') function is_masked($val) { return $val === null || strpos($val, '***') !== false; } function mask_name($v) { if (!$v) return $v; $v = trim($v); $len = mb_strlen($v, 'UTF-8'); if ($len <= 2) return '***'; return mb_substr($v, 0, 2, 'UTF-8') . str_repeat('*', min(3, $len - 2)); } function mask_phone($v) { if (!$v) return $v; $digits = preg_replace('/[^0-9]/', '', $v); $len = strlen($digits); if ($len <= 4) return '****'; if ($len <= 8) return substr($digits, 0, 4) . str_repeat('*', $len - 4); return substr($digits, 0, 4) . str_repeat('*', $len - 7) . substr($digits, -3); } function mask_email($v) { if (!$v || strpos($v, '@') === false) return $v; [$local, $domain] = explode('@', $v, 2); $show = mb_substr($local, 0, min(2, mb_strlen($local, 'UTF-8')), 'UTF-8'); return $show . '***@' . $domain; } function mask_short($v) { if (!$v) return $v; $v = trim($v); $len = mb_strlen($v, 'UTF-8'); if ($len <= 2) return '***'; return mb_substr($v, 0, 2, 'UTF-8') . '***'; } function mask_id($v) { if (!$v) return $v; $v = trim($v); $len = strlen($v); if ($len <= 4) return '****'; return substr($v, 0, 4) . str_repeat('*', max(3, $len - 6)) . ($len > 6 ? substr($v, -2) : ''); } function mask_address($v) { if (!$v) return $v; $v = trim($v); $len = mb_strlen($v, 'UTF-8'); if ($len <= 5) return '***'; return mb_substr($v, 0, 5, 'UTF-8') . '***'; } $batch = 500; // ============================================================ // m_patient // ============================================================ echo "=== Masking m_patient ===\n"; $total = 0; $stmt = $pdo->prepare("UPDATE m_patient SET M_PatientName = ?, M_PatientHP = ?, M_PatientPhone = ?, M_PatientEmail = ?, M_PatientPOB = ?, M_PatientIDNumber = ?, M_PatientNIK = ?, M_PatientNIP = ? WHERE M_PatientID = ?"); while (true) { // Skip rows already masked (ada '***' di nama) $rows = $pdo->query( "SELECT M_PatientID, M_PatientName, M_PatientHP, M_PatientPhone, M_PatientEmail, M_PatientPOB, M_PatientIDNumber, M_PatientNIK, M_PatientNIP FROM m_patient WHERE M_PatientName_enc IS NOT NULL AND M_PatientName NOT LIKE '%***%' LIMIT {$batch}" )->fetchAll(PDO::FETCH_ASSOC); if (empty($rows)) break; foreach ($rows as $row) { $stmt->execute([ mask_name($row['M_PatientName']), mask_phone($row['M_PatientHP']), mask_phone($row['M_PatientPhone']), mask_email($row['M_PatientEmail']), mask_short($row['M_PatientPOB']), mask_id($row['M_PatientIDNumber']), mask_id($row['M_PatientNIK']), mask_id($row['M_PatientNIP']), $row['M_PatientID'], ]); $total++; } echo " {$total} rows...\n"; } echo "m_patient selesai: {$total} rows\n\n"; // ============================================================ // m_patientaddress // ============================================================ echo "=== Masking m_patientaddress ===\n"; $total = 0; $stmt2 = $pdo->prepare("UPDATE m_patientaddress SET M_PatientAddressDescription = ?, M_PatientAddressEmail = ?, M_PatientAddressPhone = ? WHERE M_PatientAddressID = ?"); while (true) { $rows = $pdo->query( "SELECT M_PatientAddressID, M_PatientAddressDescription, M_PatientAddressEmail, M_PatientAddressPhone FROM m_patientaddress WHERE M_PatientAddressDescription_enc IS NOT NULL AND (M_PatientAddressDescription IS NULL OR M_PatientAddressDescription NOT LIKE '%***%') LIMIT {$batch}" )->fetchAll(PDO::FETCH_ASSOC); if (empty($rows)) break; foreach ($rows as $row) { $stmt2->execute([ mask_address($row['M_PatientAddressDescription']), mask_email($row['M_PatientAddressEmail']), mask_phone($row['M_PatientAddressPhone']), $row['M_PatientAddressID'], ]); $total++; } echo " {$total} rows...\n"; } echo "m_patientaddress selesai: {$total} rows\n\n"; echo "=== Masking plaintext selesai ===\n"; echo "Catatan: data asli tetap tersimpan aman di kolom _enc\n";