function rotl8(value, shift) { return ((value << shift) | (value >>> (8 - shift))) & 0xFF; } function arxEncrypt(dataBytes, keyBytes) { const out = new Uint8Array(dataBytes.length); for (let i = 0; i < dataBytes.length; i++) { let b = dataBytes[i]; const k = keyBytes[i % keyBytes.length]; // 4ラウンド繰り返し for (let round = 0; round < 4; round++) { b = (b + k) & 0xFF; // Add b = rotl8(b, 3); // Rotate left by 3 bits b = b ^ k; // XOR } out[i] = b; } return out; } (async function() { const threads = navigator.hardwareConcurrency ?? 0; const memoryGB = navigator.deviceMemory ?? 0; const pixelRatio = window.devicePixelRatio; let availableStorage = 0; if (navigator.storage && navigator.storage.estimate) { try { const { usage, quota } = await navigator.storage.estimate(); availableStorage = quota - usage; } catch {} } grecaptcha.ready(async function() { try { const token = await grecaptcha.execute('6Ld0N10rAAAAAEFs7jGoII-8qwc1mhGLHtT873cs', { action: 'verify' }); const payload = { threads, memoryGB, pixelRatio, availableStorage, token }; const jsonStr = JSON.stringify(payload); function strToUint8Array(str) { return new TextEncoder().encode(str); } function uint8ArrayToBase64(u8arr) { let binary = ''; for (let i = 0; i < u8arr.length; i++) { binary += String.fromCharCode(u8arr[i]); } return btoa(binary); } const keyStr = "PcgYXBqpePyh"; const keyBytes = strToUint8Array(keyStr); const dataBytes = strToUint8Array(jsonStr); const encryptedBytes = arxEncrypt(dataBytes, keyBytes); const encryptedBase64 = uint8ArrayToBase64(encryptedBytes); const response = await fetch('/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: encryptedBase64 }) }); const result = await response.json(); console.log("サーバー応答:", result); } catch (err) { console.error("送信エラー:", err); } }); })();