diff --git a/app/templates/gerador_chave.html b/app/templates/gerador_chave.html index f6d9042..f4f9cf3 100644 --- a/app/templates/gerador_chave.html +++ b/app/templates/gerador_chave.html @@ -1,15 +1,31 @@ {% extends "base.html" %} -{% block titulo %}Gerador de Chave de Reativação{% endblock %} +{% block titulo %}Gerador de Chave{% endblock %} {% block conteudo %}
GTI Grupo -

Gerador de Chave de Reativação

+

Gerador de Chave

+ + + - - +
+ + +
+ + @@ -23,6 +39,9 @@ const CHAVE_INTERNA = "YUQL23KL23DF90WI5E1JAS467NMCXXL6JAOAUWWMCL0AOMM4A4VZYW9KHJUI2347" + "EJHJKDF3424SKL K3LAKDJSL9RTIKJ"; +// ========================== +// REATIVAÇÃO — mês/cliente/ano cifrados por inteiro (22 caracteres) +// ========================== function gerarReativacao(codigoCliente, mes, ano, byteInicial = null) { const cliente = String(codigoCliente).padStart(6, '0'); const texto = String(mes).padStart(2, '0') + cliente + String(ano).slice(-2); @@ -40,8 +59,39 @@ function gerarReativacao(codigoCliente, mes, ano, byteInicial = null) { return resultado.map(v => v.toString(16).padStart(2, '0').toUpperCase()).join(''); } +// ========================== +// INSTALAÇÃO — só a modalidade ("30"=ALUGUEL / "00"=COMPRA) é cifrada +// (mesmo algoritmo de cifra da reativação, texto diferente); o valor +// derivado do código do cliente (cliente×19+31) entra sem cifrar, no +// meio dos 6 caracteres cifrados (3 antes + 3 depois). +// ========================== +function gerarInstalacao(codigoCliente, modalidade, byteInicial = null) { + const clienteNum = parseInt(String(codigoCliente), 10) || 0; + const valorCliente = clienteNum * 19 + 31; + const textoModalidade = modalidade === 'ALUGUEL' ? '30' : '00'; + + const aleatorio = byteInicial !== null ? byteInicial : Math.floor(Math.random() * 256); + let anterior = aleatorio; + const bytes = [aleatorio]; + for (let i = 0; i < textoModalidade.length; i++) { + const valor = (textoModalidade.charCodeAt(i) + anterior) % 255; + const cifrado = valor ^ CHAVE_INTERNA.charCodeAt(i % CHAVE_INTERNA.length); + bytes.push(cifrado); + anterior = cifrado; + } + + const criptografado = bytes.map(v => v.toString(16).padStart(2, '0').toUpperCase()).join(''); + const parte1 = criptografado.substring(0, 3); + const parte2 = criptografado.substring(3, 6); + return `${parte1}${valorCliente}${parte2}`; +} + +const $tipo = document.getElementById('tipo'); const $codigo = document.getElementById('codigo'); const $referencia = document.getElementById('referencia'); +const $modalidade = document.getElementById('modalidade'); +const $camposReativacao = document.getElementById('campos-reativacao'); +const $camposInstalacao = document.getElementById('campos-instalacao'); const $erro = document.getElementById('erro'); const $resultado = document.getElementById('resultado'); const $copiar = document.getElementById('copiar'); @@ -51,6 +101,12 @@ const $copiar = document.getElementById('copiar'); $referencia.value = `${hoje.getFullYear()}-${String(hoje.getMonth() + 1).padStart(2, '0')}`; })(); +$tipo.addEventListener('change', () => { + const ehReativacao = $tipo.value === 'reativacao'; + $camposReativacao.style.display = ehReativacao ? 'block' : 'none'; + $camposInstalacao.style.display = ehReativacao ? 'none' : 'block'; +}); + function mostrarErro(msg) { $erro.textContent = msg; $erro.style.display = 'block'; @@ -63,13 +119,19 @@ document.getElementById('gerar').addEventListener('click', () => { const codigoCliente = String($codigo.value || '').trim(); if (!/^[0-9]{1,6}$/.test(codigoCliente)) return mostrarErro('Código do cliente deve ter até 6 dígitos numéricos.'); const codigoFormatado = codigoCliente.padStart(6, '0'); - if (!/^\d{4}-\d{2}$/.test($referencia.value)) return mostrarErro('Selecione o mês/ano de referência.'); - const [anoStr, mesStr] = $referencia.value.split('-'); - const mesNum = Number(mesStr), anoNum = Number(anoStr); - if (!(mesNum >= 1 && mesNum <= 12)) return mostrarErro('Mês fora do intervalo 1-12.'); - if (!(anoNum >= 2000 && anoNum <= 2100)) return mostrarErro('Ano inválido (use entre 2000 e 2100).'); - const chave = gerarReativacao(codigoFormatado, mesNum, anoNum); + let chave; + if ($tipo.value === 'reativacao') { + if (!/^\d{4}-\d{2}$/.test($referencia.value)) return mostrarErro('Selecione o mês/ano de referência.'); + const [anoStr, mesStr] = $referencia.value.split('-'); + const mesNum = Number(mesStr), anoNum = Number(anoStr); + if (!(mesNum >= 1 && mesNum <= 12)) return mostrarErro('Mês fora do intervalo 1-12.'); + if (!(anoNum >= 2000 && anoNum <= 2100)) return mostrarErro('Ano inválido (use entre 2000 e 2100).'); + chave = gerarReativacao(codigoFormatado, mesNum, anoNum); + } else { + chave = gerarInstalacao(codigoFormatado, $modalidade.value); + } + $resultado.textContent = chave; $resultado.style.display = 'block'; $copiar.style.display = 'inline-block'; diff --git a/tests/test_router_chave_manual.py b/tests/test_router_chave_manual.py index d4a786a..a690dd3 100644 --- a/tests/test_router_chave_manual.py +++ b/tests/test_router_chave_manual.py @@ -14,7 +14,8 @@ def test_pagina_gerador_carrega(): resposta = client.get("/gerador-chave") assert resposta.status_code == 200 assert "gerarReativacao" in resposta.text - assert "Gerador de Chave de Reativação" in resposta.text + assert "gerarInstalacao" in resposta.text + assert "Gerador de Chave" in resposta.text def test_pagina_gerador_nao_grava_nada():