☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta ebcdic. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta ebcdic. Mostrar todas as mensagens

sábado, 11 de julho de 2026

CNPJ Alfanumérico sem Mistérios

 

Bellacosa Mainframe e o cnpj alfanumerico sem misterios

☕ Um Café no Bellacosa Mainframe

CNPJ Alfanumérico sem Mistérios

Quando o Programador COBOL Descobre que o Campo Continua com 14 Posições, mas o Mundo Inteiro ao Redor Dele Precisa Mudar

Durante décadas, o programador COBOL brasileiro olhou para o CNPJ como quem observa uma estrutura absolutamente estável:

99.999.999/9999-99

Quatorze algarismos. Sempre numérico. Frequentemente armazenado em um campo PIC 9(14), talvez compactado em COMP-3, validado por uma rotina de módulo 11 e utilizado como chave em arquivos VSAM, tabelas Db2, mapas BMS, mensagens MQ, arquivos fiscais e milhões de transações batch.

Parecia um daqueles contratos eternos do processamento corporativo.

Mas eis que surge uma nova especificação no horizonte:

AA.AAA.AAA/AAAA-99

O tamanho permanece com 14 posições, a máscara visual continua praticamente igual e os dois dígitos verificadores permanecem numéricos. Porém, as primeiras doze posições passam a aceitar números e letras maiúsculas de A a Z.

Para um usuário comum, isso pode parecer uma pequena mudança de formulário.

Para um programador COBOL, é uma alteração estrutural capaz de atravessar todo o ecossistema corporativo.

É aquele tipo de manutenção em que alguém diz:

“É só permitir letras no CNPJ.”

E três semanas depois existe uma War Room com quarenta pessoas, cinco fornecedores, dois bancos de dados, quatro sistemas satélites e um arquivo histórico criado em 1997 que ninguém sabia que ainda estava em produção.

Bem-vindo, Padawan, ao verdadeiro significado de mudança de domínio de dados.


1. O que é o CNPJ alfanumérico?

O CNPJ alfanumérico é o novo formato do identificador utilizado pelo Cadastro Nacional da Pessoa Jurídica.

A inscrição continuará possuindo 14 posições:

AA.AAA.AAA/AAAA-DV

Onde:

Posições 01 a 08: raiz da entidade
Posições 09 a 12: número de ordem do estabelecimento
Posições 13 e 14: dígitos verificadores numéricos

As primeiras doze posições poderão conter:

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z

Os dois últimos caracteres continuarão sendo algarismos calculados pelo método de módulo 11.

Exemplos possíveis:

12.345.678/0001-95
AA.345.678/0003-29
AA.345.678/000A-29
12.345.678/000A-08
65.9BR.JGJ/0001-03

O último exemplo é apresentado pelo próprio simulador nacional da Receita como um identificador fictício de teste. (Receita Federal)

Observe o detalhe importante: não existe uma posição reservada exclusivamente para letras. Qualquer uma das primeiras doze posições poderá ser alfanumérica.

Portanto, esta validação está errada:

NN.NNN.NNN/AAAA-NN

A definição correta é:

XX.XXX.XXX/XXXX-NN

Em que cada X aceita um algarismo ou uma letra maiúscula.


2. Por que o CNPJ precisou mudar?

A origem da mudança é bastante pragmática: o crescimento contínuo do número de inscrições estava aproximando o modelo exclusivamente numérico de seus limites de capacidade.

Ao introduzir letras nas doze posições principais, a quantidade de combinações possíveis cresce de forma gigantesca.

No formato puramente numérico, do ponto de vista matemático bruto, doze posições oferecem:

10¹² combinações

Com 36 símbolos possíveis por posição — dez algarismos e 26 letras — o espaço teórico passa a ser:

36¹² combinações

Isso corresponde a aproximadamente:

4.738.381.338.321.616.896

Ou cerca de 4,7 quintilhões de combinações teóricas.

Naturalmente, nem todas serão necessariamente usadas: existem regras de geração, reservas técnicas, controle de duplicidade, combinações que podem ser bloqueadas e outras restrições administrativas. Ainda assim, a expansão é monumental.

Segundo a Receita Federal, o objetivo é evitar o esgotamento dos números disponíveis, garantir a continuidade do cadastro e preservar a identificação única das entidades. (Serviços e Informações do Brasil)

É uma solução bastante conhecida na engenharia de sistemas.

Quando o espaço de chaves está ficando pequeno, temos três caminhos principais:

  1. aumentar o tamanho do campo;

  2. mudar a representação;

  3. criar um novo identificador paralelo.

A Receita escolheu ampliar o alfabeto sem aumentar o comprimento.

Essa decisão reduz impactos visuais e documentais, pois o CNPJ continua tendo 14 posições. Entretanto, ela transfere grande parte da complexidade para os sistemas que assumiram, durante décadas, que CNPJ era um número.


3. Quando começa a implantação?

A regulamentação foi estabelecida pela Instrução Normativa RFB nº 2.229, publicada em outubro de 2024, alterando a disciplina cadastral anterior. O projeto oficial estabeleceu julho de 2026 como período de implantação. (Serviços e Informações do Brasil)

Em atualização divulgada pela Receita Federal em julho de 2026, o início operacional foi detalhado para ocorrer a partir de 31 de julho de 2026, com emissão progressiva dos primeiros identificadores no novo formato. (Serviços e Informações do Brasil)

Isso é importante porque documentos antigos podem mencionar genericamente “julho de 2026” ou até “1º de julho”. O planejamento mais recente divulgado pela Receita aponta o final do mês como início efetivo da geração.

Os CNPJs já existentes não serão convertidos, substituídos ou cancelados. Eles continuarão válidos exatamente como estão. O novo formato será utilizado progressivamente em novas inscrições. (Serviços e Informações do Brasil)

Isso cria um mundo de coexistência:

CNPJ antigo: 12.345.678/0001-95
CNPJ novo:   AB.3C5.678/00D1-42

Ambos deverão ser aceitos.

Portanto, não existe “migração de todos os CNPJs”. Existe uma migração dos sistemas para aceitar os dois formatos.

Essa diferença parece pequena, mas muda completamente a estratégia de implantação.


4. A grande armadilha: CNPJ nunca deveria ter sido tratado como número

Este é o momento em que o Mestre Bellacosa coloca a caneca sobre a mesa e pergunta ao Padawan:

CNPJ é realmente um número?

Matematicamente, não.

CNPJ é um identificador.

Ele não representa uma quantidade. Você não soma dois CNPJs, não calcula média de CNPJ e não divide um CNPJ por outro.

O fato de ele ter sido historicamente composto apenas por algarismos levou milhares de sistemas a armazená-lo como dado numérico.

Exemplo clássico:

01  WS-CNPJ.
    05 WS-CNPJ-BASE       PIC 9(12).
    05 WS-CNPJ-DV         PIC 9(02).

Ou pior:

01  WS-CNPJ               PIC 9(14) COMP-3.

O segundo formato economiza espaço, mas impede completamente o armazenamento de letras.

O novo modelo deixa explícito algo que a modelagem já deveria ter reconhecido:

CNPJ é texto estruturado.

A definição mais adequada passa a ser:

01  WS-CNPJ.
    05 WS-CNPJ-BASE       PIC X(12).
    05 WS-CNPJ-DV         PIC 9(02).

Ou, para facilitar movimentações:

01  WS-CNPJ-NORMALIZADO   PIC X(14).

O termo “normalizado” significa armazenar sem pontuação:

AB3C567800D142

Enquanto a representação formatada seria:

AB.3C5.678/00D1-42

Uma boa arquitetura separa essas duas coisas:

valor canônico: AB3C567800D142
apresentação:   AB.3C5.678/00D1-42

Não armazene pontos, barra e hífen na chave principal, salvo quando houver uma justificativa muito específica. Formatação pertence à camada de apresentação.


5. O impacto real em sistemas COBOL

Trocar PIC 9(14) por PIC X(14) é apenas o primeiro passo.

O impacto poderá alcançar:

  • copybooks;

  • arquivos sequenciais;

  • VSAM;

  • tabelas Db2;

  • mapas BMS;

  • telas IMS;

  • programas online;

  • jobs batch;

  • sort cards;

  • interfaces MQ;

  • APIs;

  • JSON e XML;

  • arquivos SPED;

  • relatórios;

  • chaves de indexação;

  • critérios de pesquisa;

  • rotinas de mascaramento;

  • validações de entrada;

  • programas Java, Natural, PL/I e Assembler integrados;

  • ferramentas de prevenção a fraude;

  • trilhas de auditoria;

  • data warehouses;

  • data lakes;

  • planilhas e sistemas departamentais.

Vamos analisar alguns exemplos.

5.1 Copybook antigo

05 CLIENTE-CNPJ           PIC 9(14).

Nova definição:

05 CLIENTE-CNPJ           PIC X(14).

Parece simples, mas todos os programas que incluem esse copybook precisam ser analisados.

Este comando pode deixar de compilar ou mudar de comportamento:

IF CLIENTE-CNPJ IS NUMERIC

Esta movimentação pode gerar problema:

COMPUTE WS-CHAVE = CLIENTE-CNPJ + 100

Esta classificação pode mudar:

SORT FIELDS=(1,14,ZD,A)

A definição ZD, de zoned decimal, não aceita letras. Será necessário tratar o campo como caractere:

SORT FIELDS=(1,14,CH,A)

Todavia, há uma nova questão: qual será a ordem esperada? Ordem binária EBCDIC? Ordem lógica da aplicação? Ordem usada por um sistema distribuído em ASCII?


6. O Easter egg que todo programador de mainframe precisa conhecer: ASCII não é EBCDIC

O algoritmo oficial do dígito verificador converte cada caractere utilizando seu valor na tabela ASCII, subtraindo 48.

Assim:

'0' ASCII 48  → 48 - 48 = 0
'1' ASCII 49  → 49 - 48 = 1
...
'9' ASCII 57  → 57 - 48 = 9

'A' ASCII 65  → 65 - 48 = 17
'B' ASCII 66  → 66 - 48 = 18
...
'Z' ASCII 90  → 90 - 48 = 42

Observe que A não vale 10. Ela vale 17.

Essa diferença existe porque o cálculo preserva a relação com os códigos ASCII.

Agora vem o perigo: z/OS tradicionalmente utiliza EBCDIC.

No EBCDIC, os valores dos caracteres são diferentes. Além disso, as letras não ocupam necessariamente uma sequência contínua equivalente à encontrada em ASCII.

Portanto, uma implementação como esta é conceitualmente perigosa no mainframe:

COMPUTE WS-VALOR =
    FUNCTION ORD(WS-CARACTERE) - 48

Ela pode funcionar em determinada plataforma, compilador ou codificação e falhar em outra.

O algoritmo precisa usar o valor lógico definido pela especificação, e não o código físico local do caractere.

A abordagem segura é mapear explicitamente:

0 → 0
1 → 1
...
9 → 9
A → 17
B → 18
...
Z → 42

Aqui está um maravilhoso Easter egg da modernização brasileira:

Um identificador nacional criado no século XXI obriga o programador COBOL a revisitar uma das guerras de codificação mais antigas da computação: ASCII versus EBCDIC.

No Mainframe, o detalhe nunca desaparece. Ele apenas espera pacientemente dentro de um byte.


7. Como calcular o dígito verificador

O cálculo continua utilizando módulo 11, mas agora cada caractere precisa ser convertido para seu valor numérico lógico.

Para o primeiro dígito verificador, aplicam-se os seguintes pesos às doze primeiras posições:

Posição:  01 02 03 04 05 06 07 08 09 10 11 12
Peso:      5  4  3  2  9  8  7  6  5  4  3  2

Cada valor é multiplicado pelo peso correspondente.

Depois:

RESTO = SOMA MOD 11

A regra do dígito é:

Se RESTO for 0 ou 1:
    DV = 0
Senão:
    DV = 11 - RESTO

Para o segundo dígito, o primeiro DV é anexado ao final e aplicam-se os pesos:

Posição:  01 02 03 04 05 06 07 08 09 10 11 12 DV1
Peso:      6  5  4  3  2  9  8  7  6  5  4  3  2

O mesmo cálculo de módulo 11 é repetido. A Receita mantém documentação técnica e arquivos de referência específicos para esse algoritmo. (Serviços e Informações do Brasil)


8. Estrutura COBOL recomendada

Uma estrutura didática poderia ser:

       01  WS-CNPJ.
           05 WS-CNPJ-CORPO       PIC X(12).
           05 WS-CNPJ-DV.
              10 WS-CNPJ-DV1      PIC 9.
              10 WS-CNPJ-DV2      PIC 9.

       01  WS-CONTROLE.
           05 WS-I                PIC 99 COMP.
           05 WS-VALOR            PIC 99 COMP.
           05 WS-SOMA             PIC 9(06) COMP.
           05 WS-RESTO            PIC 99 COMP.
           05 WS-CARACTERE        PIC X.

       01  WS-PESOS-DV1.
           05 FILLER              PIC X(12)
                                  VALUE X'050403020908070605040302'.

       01  WS-PESOS-DV1-R REDEFINES WS-PESOS-DV1.
           05 WS-PESO1            PIC X OCCURS 12 TIMES.

       01  WS-PESOS-DV2.
           05 FILLER              PIC X(13)
                              VALUE X'06050403020908070605040302'.

       01  WS-PESOS-DV2-R REDEFINES WS-PESOS-DV2.
           05 WS-PESO2            PIC X OCCURS 13 TIMES.

Em uma implementação corporativa, talvez seja mais legível declarar os pesos como campos numéricos individuais ou carregá-los em uma tabela durante a inicialização.

Por exemplo:

       01  WS-TAB-PESO1.
           05 WS-PESO1 OCCURS 12 TIMES PIC 9 COMP.

E inicializar:

       MOVE 5 TO WS-PESO1(1)
       MOVE 4 TO WS-PESO1(2)
       MOVE 3 TO WS-PESO1(3)
       MOVE 2 TO WS-PESO1(4)
       MOVE 9 TO WS-PESO1(5)
       MOVE 8 TO WS-PESO1(6)
       MOVE 7 TO WS-PESO1(7)
       MOVE 6 TO WS-PESO1(8)
       MOVE 5 TO WS-PESO1(9)
       MOVE 4 TO WS-PESO1(10)
       MOVE 3 TO WS-PESO1(11)
       MOVE 2 TO WS-PESO1(12)

É mais extenso, porém muito fácil de auditar.

No mundo fiscal, clareza costuma valer mais do que cinco linhas economizadas.


9. Conversão segura do caractere

Uma rotina simples pode utilizar EVALUATE:

       CONVERTER-CARACTERE.
           EVALUATE WS-CARACTERE
               WHEN '0' MOVE 0  TO WS-VALOR
               WHEN '1' MOVE 1  TO WS-VALOR
               WHEN '2' MOVE 2  TO WS-VALOR
               WHEN '3' MOVE 3  TO WS-VALOR
               WHEN '4' MOVE 4  TO WS-VALOR
               WHEN '5' MOVE 5  TO WS-VALOR
               WHEN '6' MOVE 6  TO WS-VALOR
               WHEN '7' MOVE 7  TO WS-VALOR
               WHEN '8' MOVE 8  TO WS-VALOR
               WHEN '9' MOVE 9  TO WS-VALOR
               WHEN 'A' MOVE 17 TO WS-VALOR
               WHEN 'B' MOVE 18 TO WS-VALOR
               WHEN 'C' MOVE 19 TO WS-VALOR
               WHEN 'D' MOVE 20 TO WS-VALOR
               WHEN 'E' MOVE 21 TO WS-VALOR
               WHEN 'F' MOVE 22 TO WS-VALOR
               WHEN 'G' MOVE 23 TO WS-VALOR
               WHEN 'H' MOVE 24 TO WS-VALOR
               WHEN 'I' MOVE 25 TO WS-VALOR
               WHEN 'J' MOVE 26 TO WS-VALOR
               WHEN 'K' MOVE 27 TO WS-VALOR
               WHEN 'L' MOVE 28 TO WS-VALOR
               WHEN 'M' MOVE 29 TO WS-VALOR
               WHEN 'N' MOVE 30 TO WS-VALOR
               WHEN 'O' MOVE 31 TO WS-VALOR
               WHEN 'P' MOVE 32 TO WS-VALOR
               WHEN 'Q' MOVE 33 TO WS-VALOR
               WHEN 'R' MOVE 34 TO WS-VALOR
               WHEN 'S' MOVE 35 TO WS-VALOR
               WHEN 'T' MOVE 36 TO WS-VALOR
               WHEN 'U' MOVE 37 TO WS-VALOR
               WHEN 'V' MOVE 38 TO WS-VALOR
               WHEN 'W' MOVE 39 TO WS-VALOR
               WHEN 'X' MOVE 40 TO WS-VALOR
               WHEN 'Y' MOVE 41 TO WS-VALOR
               WHEN 'Z' MOVE 42 TO WS-VALOR
               WHEN OTHER
                   MOVE 99 TO WS-VALOR
           END-EVALUATE.

Sim, são muitas linhas.

Porém, esta rotina é:

  • explícita;

  • independente de ASCII ou EBCDIC;

  • portável;

  • auditável;

  • fácil de testar;

  • fiel à especificação.

Em ambientes modernos, também seria possível usar uma tabela indexada. Ainda assim, documente claramente por que A = 17.

Sem essa documentação, algum programador bem-intencionado poderá “corrigir” a rotina no futuro, fazendo A = 10, e produzir um belo incidente fiscal.


10. Cálculo COBOL simplificado do primeiro DV

       CALCULAR-DV1.
           MOVE ZERO TO WS-SOMA

           PERFORM VARYING WS-I FROM 1 BY 1
                   UNTIL WS-I > 12

               MOVE WS-CNPJ-CORPO(WS-I:1)
                 TO WS-CARACTERE

               PERFORM CONVERTER-CARACTERE

               IF WS-VALOR = 99
                   MOVE 'S' TO WS-ERRO-CNPJ
                   EXIT PARAGRAPH
               END-IF

               COMPUTE WS-SOMA =
                   WS-SOMA +
                   (WS-VALOR * WS-PESO1(WS-I))
           END-PERFORM

           COMPUTE WS-RESTO =
               FUNCTION MOD(WS-SOMA, 11)

           IF WS-RESTO < 2
               MOVE ZERO TO WS-CNPJ-DV1
           ELSE
               COMPUTE WS-CNPJ-DV1 = 11 - WS-RESTO
           END-IF.

Para o segundo DV, processe novamente as doze posições e depois multiplique o primeiro dígito pelo peso final 2.

       CALCULAR-DV2.
           MOVE ZERO TO WS-SOMA

           PERFORM VARYING WS-I FROM 1 BY 1
                   UNTIL WS-I > 12

               MOVE WS-CNPJ-CORPO(WS-I:1)
                 TO WS-CARACTERE

               PERFORM CONVERTER-CARACTERE

               COMPUTE WS-SOMA =
                   WS-SOMA +
                   (WS-VALOR * WS-PESO2(WS-I))
           END-PERFORM

           COMPUTE WS-SOMA =
               WS-SOMA + (WS-CNPJ-DV1 * 2)

           COMPUTE WS-RESTO =
               FUNCTION MOD(WS-SOMA, 11)

           IF WS-RESTO < 2
               MOVE ZERO TO WS-CNPJ-DV2
           ELSE
               COMPUTE WS-CNPJ-DV2 = 11 - WS-RESTO
           END-IF.

Em produção, acrescente tratamento formal de erro, mensagens padronizadas, logging, retorno de condição e testes automatizados.


11. Normalização da entrada

O usuário poderá informar:

AB.123.CD4/0001-55

Ou:

AB123CD4000155

A aplicação deve decidir qual contrato aceita.

Uma boa rotina de normalização pode:

  1. remover ., / e -;

  2. eliminar espaços laterais;

  3. converter letras minúsculas em maiúsculas;

  4. verificar se restaram exatamente 14 caracteres;

  5. validar as primeiras doze posições;

  6. confirmar que as duas últimas são numéricas;

  7. calcular e comparar os dígitos verificadores.

Não aceite silenciosamente qualquer caractere.

Os permitidos nas primeiras posições são apenas:

0-9
A-Z

Portanto, estes devem ser rejeitados:

Á
Ç
@
#
espaço
underscore
letra minúscula sem normalização

A Receita orienta que os sistemas considerem todas as letras de A a Z. O controle de combinações eventualmente proibidas, como formações ofensivas ou confusas, será realizado internamente pela própria Receita; as empresas não precisam reproduzir essa lista.


12. Não use IS NUMERIC para validar o CNPJ inteiro

Antes:

IF WS-CNPJ IS NUMERIC
    CONTINUE
ELSE
    MOVE 'CNPJ INVALIDO' TO WS-MENSAGEM
END-IF

Depois da mudança, isso rejeitará corretamente todos os novos CNPJs — o que significa que estará funcionalmente errado.

A validação precisa ser segmentada:

Posições 1 a 12:
    letras A-Z ou números 0-9

Posições 13 e 14:
    somente números

Conjunto completo:
    dígito verificador válido

Uma verificação de formato nunca substitui a validação do DV.

Este identificador possui formato válido:

ABCDEFGHIJKL00

Mas não significa que seus dígitos verificadores sejam corretos ou que exista uma entidade registrada com ele.

São três conceitos diferentes:

formato válido
dígito verificador válido
cadastro existente

Um programa maduro não mistura essas responsabilidades.


13. Db2: o problema escondido nas colunas DECIMAL

Imagine esta tabela:

CREATE TABLE CLIENTE
(
    CNPJ DECIMAL(14,0) NOT NULL,
    NOME VARCHAR(100)
);

Ela não poderá armazenar o novo formato.

A coluna precisará tornar-se:

CNPJ CHAR(14)

ou:

CNPJ VARCHAR(14)

Para identificadores de tamanho fixo, CHAR(14) costuma ser uma escolha natural.

Entretanto, alterar uma coluna primária pode envolver:

  • índices;

  • chaves estrangeiras;

  • views;

  • triggers;

  • packages Db2;

  • programas com SQL estático;

  • DCLGENs;

  • rotinas ETL;

  • replicação;

  • unloads;

  • data warehouses;

  • APIs;

  • relatórios;

  • programas que usam host variable numérica.

Uma host variable antiga:

01 HV-CNPJ PIC S9(14) COMP-3.

precisará ser substituída por:

01 HV-CNPJ PIC X(14).

Depois será necessário regenerar o DCLGEN, recompilar, realizar precompile, bind e testes de regressão.

Não trate isso apenas como alteração de tela.


14. Arquivos VSAM e chaves

Considere um KSDS cujo CNPJ esteja na chave:

KEYS(14 0)

O comprimento continua igual. Isso parece ótimo.

Mas se o campo era interpretado como numérico em programas, sorts ou relatórios, o comportamento precisará ser revisto.

Outro cuidado é a ordenação.

Em EBCDIC, a sequência de comparação de caracteres é diferente da sequência ASCII. Um arquivo ordenado no mainframe pode produzir uma ordem diferente de um banco distribuído.

Para identificadores únicos, isso normalmente não invalida a chave. Contudo, pode afetar:

  • relatórios;

  • comparações de faixa;

  • cargas ordenadas;

  • reconciliações;

  • merge entre arquivos de plataformas diferentes;

  • processamento com START e READ NEXT.

Evite atribuir significado comercial à ordem lexical do CNPJ.

Um CNPJ “maior” não é mais novo, mais importante ou pertencente a determinada região.


15. Letras não representam estado, porte ou natureza jurídica

As letras serão atribuídas pelo sistema de geração e não carregarão inteligência sobre:

  • Unidade da Federação;

  • município;

  • porte;

  • atividade econômica;

  • natureza jurídica;

  • regime tributário;

  • data de abertura;

  • órgão de registro.

A Receita esclarece que não haverá conexão semântica entre as letras e atributos cadastrais.

Portanto, nunca escreva uma regra como:

IF WS-CNPJ(1:1) = 'S'
    MOVE 'SAO PAULO' TO WS-UF
END-IF

O identificador é opaco.

Ele identifica a entidade, mas não deve ser “decodificado” para inferir informações.

Essa é uma prática moderna importante: identificadores não devem carregar regras de negócio ocultas, a menos que isso faça parte de uma especificação formal.


16. E o famoso sufixo 0001?

Historicamente, muitos sistemas assumiram:

0001 = matriz
qualquer outro valor = filial

A própria Receita informa que 0001 continuará inicialmente associado à matriz quando o número for gerado. Porém, essa não é uma associação permanente: uma filial poderá posteriormente tornar-se o estabelecimento principal, mesmo possuindo outro número de ordem.

Portanto, isto é uma regra frágil:

IF WS-CNPJ(9:4) = '0001'
    MOVE 'MATRIZ' TO WS-TIPO
ELSE
    MOVE 'FILIAL' TO WS-TIPO
END-IF

A informação de matriz ou filial deve vir de um atributo cadastral confiável, não de uma interpretação eterna do sufixo.

Além disso, o número de ordem poderá conter letras:

000A
00B7
A001

Quem armazenou a ordem da filial em PIC 9(4) também terá trabalho.


17. APIs, JSON e XML

Este JSON antigo já tratava corretamente o CNPJ:

{
  "cnpj": "12345678000195"
}

Este, não:

{
  "cnpj": 12345678000195
}

O identificador deve ser enviado como string.

Novo exemplo:

{
  "cnpj": "AB3C567800D142"
}

Em OpenAPI:

cnpj:
  type: string
  minLength: 14
  maxLength: 14
  pattern: '^[A-Z0-9]{12}[0-9]{2}$'

A expressão regular valida apenas a estrutura. O cálculo do DV continuará necessário.

Para o COBOL usando JSON GENERATE, defina o campo como alfanumérico:

05 CNPJ PIC X(14).

Revise também os schemas XML. O ecossistema de documentos fiscais eletrônicos vem publicando notas técnicas e atualizações de XSD para suportar o novo formato, incluindo NF-e, NFC-e e EFD-Reinf. (Nota Fiscal Eletrônica)


18. Estratégia de implantação sem derrubar a produção

Não faça uma alteração Big Bang sem inventário.

Uma estratégia madura pode ser dividida em ondas.

Onda 1 — Descoberta

Procure por:

PIC 9(14)
PIC 9(12)
PIC 9(8)
PIC 9(4)
COMP-3
CNPJ
CGC
CGC-CPF
NUM-CNPJ
CNPJ-NUM
IS NUMERIC
NUMERIC-EDITED

Não pesquise apenas por CNPJ.

Sistemas antigos podem ainda usar o termo CGC, nome histórico anterior do cadastro.

Procure também:

DECIMAL(14,0)
NUMERIC(14)
BIGINT
CHAR(14)

O objetivo é construir um inventário de:

  • fontes;

  • copybooks;

  • tabelas;

  • arquivos;

  • interfaces;

  • relatórios;

  • rotinas de validação;

  • consumidores externos.

Onda 2 — Classificação

Classifique os componentes:

A – armazena CNPJ
B – recebe CNPJ
C – envia CNPJ
D – valida CNPJ
E – formata CNPJ
F – usa CNPJ como chave
G – apenas exibe CNPJ

Os itens que usam o identificador como chave ou campo numérico possuem prioridade maior.

Onda 3 — Modelo canônico

Defina um padrão corporativo:

CNPJ interno:     X(14), sem máscara, maiúsculo
CNPJ apresentado: XX.XXX.XXX/XXXX-XX
DV:               módulo 11 oficial
Codificação:      contrato independente de ASCII/EBCDIC

Onda 4 — Compatibilidade dupla

Teste simultaneamente:

CNPJ exclusivamente numérico
CNPJ com uma letra
CNPJ com várias letras
CNPJ com letras na raiz
CNPJ com letras na ordem
CNPJ com zero à esquerda
CNPJ inválido
DV incorreto
letra minúscula
pontuação
espaços
caracteres especiais

Onda 5 — Implantação observável

Crie métricas:

quantidade de CNPJs alfanuméricos recebidos
rejeições por formato
rejeições por DV
erros de integração
truncamentos
conversões indevidas
mensagens enviadas para DLQ
falhas em arquivos fiscais

Modernização sem observabilidade é apenas uma nova forma de torcer para que tudo funcione.


19. Casos de teste essenciais

Uma suíte mínima deveria incluir:

Caso 1 — CNPJ numérico atual

Entrada: CNPJ numérico válido
Resultado: aceito

Caso 2 — Raiz alfanumérica

Entrada: letras entre as posições 1 e 8
Resultado: aceito se o DV estiver correto

Caso 3 — Ordem alfanumérica

Entrada: letras entre as posições 9 e 12
Resultado: aceito se o DV estiver correto

Caso 4 — Identificador totalmente numérico depois da mudança

Ainda poderá ocorrer, pois a geração progressiva poderá produzir combinações exclusivamente numéricas. Não crie uma regra que exija pelo menos uma letra.

Caso 5 — Minúsculas

ab12cd34000199

Defina o comportamento:

normalizar para maiúsculas
ou
rejeitar por contrato

A primeira opção costuma proporcionar melhor experiência, desde que seja documentada.

Caso 6 — Caractere inválido

AB12ÇD34000199

Deve ser rejeitado.

Caso 7 — DV alfabético

AB12CD340001A9

Deve ser rejeitado, pois as duas últimas posições são exclusivamente numéricas.

Caso 8 — Campo com pontuação

AB.12C.D34/0001-99

Valide após a normalização, caso a interface permita máscara.

Caso 9 — Valor vazio

Decida se o campo é obrigatório ou opcional. Não transforme espaços em zeros silenciosamente.

Caso 10 — Integração EBCDIC/ASCII

Envie o mesmo CNPJ entre:

COBOL/zOS
Java/Linux
API REST
MQ
arquivo UTF-8
arquivo EBCDIC

Confirme que o valor não sofreu tradução incorreta.


20. Use o simulador oficial

A Receita Federal disponibilizou um simulador capaz de gerar CNPJs fictícios, numéricos e alfanuméricos, inclusive combinações para matriz e filiais. A ferramenta pode gerar lotes para testes e exportação, auxiliando equipes de desenvolvimento na adaptação. (Receita Federal)

Essa é uma excelente oportunidade para criar:

  • massa de testes unitários;

  • arquivos de entrada;

  • cenários de integração;

  • registros Db2;

  • entradas de CICS;

  • mensagens MQ;

  • testes de API;

  • validação de relatórios.

Não invente apenas três exemplos manualmente.

Gere centenas de casos e execute-os automaticamente.

No pipeline:

Build
  ↓
Análise estática
  ↓
Teste unitário do DV
  ↓
Teste com CNPJ numérico
  ↓
Teste com CNPJ alfanumérico
  ↓
Teste de integração
  ↓
Teste de regressão
  ↓
Deploy controlado

O CNPJ alfanumérico é um excelente caso de uso para ZUnit, COBOL Check, Galasa, DBB, Jenkins e pipelines corporativos.


21. Dicas do Mestre Bellacosa

Nunca converta o CNPJ para número

Não faça:

MOVE FUNCTION NUMVAL(WS-CNPJ) TO WS-CNPJ-NUM

Além de falhar com letras, isso pode eliminar zeros à esquerda.

Não remova letras para “manter compatibilidade”

Esta aberração:

AB12CD34000199 → 1234000199

destrói o identificador e pode criar colisões.

Não use espaços para substituir letras

Um campo com letras não reconhecidas deve causar erro controlado, não limpeza silenciosa.

Centralize a validação

Crie uma rotina comum, serviço ou módulo compartilhado.

Exemplo:

CALL 'VALCNPJ2'
    USING CNPJ-ENTRADA
          CNPJ-NORMALIZADO
          CODIGO-RETORNO
          MENSAGEM-RETORNO

Assim, todos os sistemas seguem a mesma regra.

Versione o copybook

Não altere um copybook crítico sem avaliar seus consumidores.

Uma estratégia possível:

CPYCNPJ1 – formato legado
CPYCNPJ2 – formato alfanumérico

Depois, migre os programas progressivamente.

Não confunda máscara com conteúdo

A máscara possui 18 caracteres:

AA.AAA.AAA/AAAA-99

O conteúdo canônico possui 14:

AAAAAAAAAAAA99

Preserve os zeros à esquerda

Como o campo passa a ser textual, a preservação fica mais natural. Ainda assim, evite funções que façam conversão numérica intermediária.

Registre o valor recebido e o normalizado

Em sistemas críticos, pode ser útil registrar:

valor original
valor normalizado
resultado da validação
origem da transação
data e hora

Isso facilita auditoria e investigação.


22. Curiosidades importantes

O número continuará público

O novo formato não é código secreto, token de rastreamento ou identificação criptografada. A Receita afirma que não existe informação escondida na composição.

Não existe inteligência artificial escolhendo o CNPJ

Apesar da palavra “alfanumérico” parecer sofisticada, a Receita esclarece que a geração não utiliza IA para atribuir significado ao número.

A chave Pix poderá usar o novo formato

Empresas com CNPJ alfanumérico poderão utilizá-lo como chave Pix, enquanto as chaves dos CNPJs numéricos existentes continuam válidas.

CNPJs numéricos e alfanuméricos coexistirão por décadas

Como os registros antigos não serão modificados, é perfeitamente possível que sistemas ainda processem CNPJs exclusivamente numéricos muitas décadas depois da implantação.

Portanto, não crie duas lógicas separadas desnecessariamente:

validador antigo
validador novo

Crie uma lógica compatível com ambos.

O algoritmo alfanumérico, quando aplicado a algarismos, preserva o mapeamento de 0 a 9, permitindo tratar o formato numérico dentro da mesma arquitetura.


23. O verdadeiro problema não está no campo

O grande risco do CNPJ alfanumérico não é a largura.

Ela continua sendo 14.

O risco está nas suposições invisíveis acumuladas durante décadas:

CNPJ sempre é numérico.
CNPJ pode ser COMP-3.
Filial sempre é 9(4).
0001 sempre significa matriz.
IS NUMERIC valida o campo.
SORT ZD funciona.
Banco pode usar DECIMAL.
JSON pode enviar um número.
A posição das letras tem significado.
ASCII e EBCDIC produzem o mesmo valor.

Cada uma dessas suposições pode estar escondida em milhares de linhas.

É por isso que bons profissionais de sistemas legados não começam mudando código.

Eles começam construindo um mapa de dependências.


Conclusão: o campo não cresceu, mas o sistema amadureceu

Padawan, o CNPJ alfanumérico é uma daquelas mudanças que ensinam uma poderosa lição de engenharia.

Durante décadas, muitos sistemas confundiram representação com significado.

O CNPJ parecia numérico porque era formado por números. Entretanto, ele nunca foi uma quantidade. Sempre foi uma chave textual de identificação.

Agora, a chegada das letras remove essa ilusão.

O programador COBOL que simplesmente trocar:

PIC 9(14)

por:

PIC X(14)

terá iniciado o trabalho.

O profissional que revisar arquivos, bancos, chaves, interfaces, módulos de validação, ordenação, codificação, APIs, documentos fiscais, observabilidade e testes terá realmente preparado o sistema.

No IBM Z aprendemos há décadas que sistemas críticos não quebram apenas por grandes revoluções.

Eles quebram por pequenas suposições que deixaram de ser verdade.

O novo CNPJ não é apenas uma letra chegando a um campo antigo.

É um lembrete de que contratos de dados também envelhecem, regras aparentemente eternas também mudam e nenhum PIC 9 deve ser considerado imortal.

Prepare seus copybooks.

Revise seus DCLGENs.

Convoque seus testes automatizados.

E nunca se esqueça do Easter egg mais importante desta jornada:

Quando a especificação disser ASCII e seu programa estiver rodando em EBCDIC, não confie no byte. Confie na regra de negócio.

Porque no Bellacosa Mainframe, até uma simples letra A pode valer 17 — e separar um processamento concluído com sucesso de uma longa madrugada examinando dumps no abençoado SDSF.


sexta-feira, 11 de outubro de 2024

JSON em COBOL no IBM Z: O Holocron das APIs Modernas – JSON GENERATE - Parte III

 

Bellacosa Mainframe e o json em cobol parte iii

JSON em COBOL no IBM Z: O Holocron das APIs Modernas

Parte 3 – JSON GENERATE

Quando o Padawan Aprende a Construir APIs REST com COBOL e Descobre que Também Pode Falar com a Galáxia

Por Bellacosa Mainframe


"JSON PARSE ensina COBOL a escutar. JSON GENERATE ensina COBOL a responder. Um Mestre Jedi precisa dominar ambos."

Mestre Bellacosa Sysprog Jedi


Introdução

Nas jornadas anteriores, o jovem Padawan descobriu algo extraordinário.

Primeiro aprendeu que COBOL moderno fala JSON.

Depois aprendeu a utilizar JSON PARSE.

Agora chega o momento em que ele percebe uma verdade ainda mais impressionante.

COBOL não apenas entende JSON.

COBOL também consegue produzir JSON de forma elegante, otimizada e extremamente rápida.

E isso é feito através de uma instrução quase tão poderosa quanto um sabre de luz recém-montado.

JSON GENERATE


O que é JSON GENERATE?

JSON GENERATE é um serializador.

Seu objetivo é simples.

Transformar estruturas COBOL em texto JSON.

Visualmente.

WORKING STORAGE


↓

JSON GENERATE


↓

JSON


↓

REST API


↓

Aplicativo


↓

Microsserviço

Em outras palavras.

Ele faz exatamente o oposto de JSON PARSE.


Antes do Enterprise COBOL 6

A vida era difícil.

Muitos sistemas faziam:

STRING

"{"

'"id":'

WS-ID

','
'"nome":"'

WS-NOME

'"'

"}"

INTO WS-BUFFER

Problemas.

Vírgulas.

Aspas.

Espaços.

Campos vazios.

Arrays.

Escape.

Tudo manual.


Padawan sofria.


O nascimento de JSON GENERATE

Enterprise COBOL Version 6.

Introduziu.

JSON GENERATE.


Mudou completamente.

Integrações.


Hoje.

Muito utilizado.

6.3

6.4

6.5


Primeiro exemplo

Passo 1

Estrutura COBOL

01 WS-CLIENTE.


05 WS-ID.
PIC 9(5).


05 WS-NOME.
PIC X(30).


05 WS-IDADE.
PIC 999.

Passo 2

JSON Buffer

01 WS-JSON.

PIC X(500).

Passo 3

Popular

MOVE 100

TO WS-ID


MOVE 'Bellacosa'

TO WS-NOME


MOVE 52

TO WS-IDADE

Passo 4

Gerar

JSON GENERATE

WS-JSON


FROM WS-CLIENTE

Passo 5

Display

DISPLAY WS-JSON

Resultado.

{

"id":100,

"nome":"Bellacosa",

"idade":52

}

Pronto.

API pronta.


Como funciona internamente?

Compilador gera.

Serializer.


Percorre.

Estrutura.

Campo.

Por campo.


Converte.

Numéricos.

Strings.

Booleans.

Occurs.


Escreve.

JSON.


Visualmente.

WS-ID


↓

Serializer


↓

"id":100

Memória

JSON continua sendo.

Texto.


Exemplo.

01 WS-JSON.

PIC X(10000).

Buffer.

Grande.


Serializer.

Preenche.


Pouco overhead.


Muito eficiente.


Campos vazios

Problema comum.


Exemplo.

MOVE SPACES

TO WS-NOME

Resultado.

"name":""

Nem sempre desejado.


SUPPRESS

Ferramenta poderosa.


Exemplo conceitual.

JSON GENERATE

WS-JSON


FROM WS-DADOS


SUPPRESS

Campos vazios.

Não aparecem.


Muito usado.

Em APIs.


OMITTED

Outra técnica.


Campo opcional.


Excelente.

Open Banking.

PIX.


NAME OF

Talvez a funcionalidade favorita.

Do Bellacosa.


COBOL.

05 WS-NOME.

JSON desejado.

"customerName"

NAME OF permite.

Mapear.


Muito elegante.


Exemplo API PIX

COBOL.

01 PIX.


05 CHAVE.


05 VALOR.


05 DATA.

JSON.

{

"chave":"abc",


"valor":100,


"data":"2026-06-25"

}

JSON GENERATE.

Faz.

Tudo.


Arrays

Muito útil.


COBOL.

05 TELEFONES.


10 TEL OCCURS 5.

JSON.

"telefones":[


"1111",


"2222"

]

Automático.


Objetos aninhados

COBOL.

01 CLIENTE.


05 DADOS.


10 ID.


10 NOME.



05 ENDERECO.


10 CIDADE.


10 CEP.

Resultado.

{

"cliente":{


"id":1,

"nome":"Bellacosa"


},

"endereco":{


"cidade":"SP"

}

}

Muito elegante.


Null

JSON suporta.


COBOL não.


Precisamos.

Decidir.


Campo vazio.


Campo omitido.


Valor padrão.


Muito importante.


UTF8

Outro cuidado.


JSON.

UTF8.


COBOL.

EBCDIC.


Conversão.

Necessária.


Especialmente.

Acentos.


José.

São Paulo.


Ç.

Ã.


Sempre testar.


Segurança

Poucos lembram.


JSON GENERATE.

Também possui.

Riscos.


Exemplo.

Dados internos.


Senha.


CPF.


Token.


Acidentalmente.

Expostos.


Exemplo.

01 CLIENTE.


05 SENHA.


PIC X(20).

JSON GENERATE.

Sem SUPPRESS.


API.

Expõe.

Senha.


Muito perigoso.


Boa prática

Criar.

Estrutura.

Específica.

API.


Nunca.

Gerar.

Diretamente.

Working Storage.

Inteira.


Pretty JSON

COBOL.

Não gera.

JSON bonito.


Compacto.


Mais eficiente.


Consumidor.

Pode formatar.


Performance

Excelente.


Serializer.

Nativo.


Compilado.


Muito rápido.


Melhor.

Que STRING.


Melhor.

Que montar.

Na mão.


Benchmark aproximado

Manual.

100%


JSON GENERATE.

Muito menor.

CPU.


Menos bugs.


Mais manutenção.


Curiosidade

Muitos aplicativos bancários.

Recebem.

JSON.

Gerado.

Por COBOL.


Usuário.

Nunca percebe.


Abre app.


Consulta saldo.


Recebe.

JSON.


Origem.

COBOL.

No z17.


APIs modernas

JSON GENERATE é usado.

Em.

z/OS Connect

CICS

Liberty

MQ

Kafka

OpenShift

Cloud Pak


Praticamente.

Todo lugar.


Bellacosa Best Practices

Sempre

Criar DTO.

Separado.


Sempre

Usar SUPPRESS.


Sempre

Validar UTF8.


Sempre

Versionar JSON.


Sempre

Documentar.

Swagger.

OpenAPI.


Nunca

Expor.

Campos internos.


Nunca

Montar.

JSON.

Na mão.

Com STRING.


Comparação

TécnicaRecomendada
STRINGNão
UNSTRINGNão
INSPECTNão
Parser próprioEvitar
JSON GENERATESim
JSON PARSESim

O Conselho do Mestre Bellacosa

Durante muitos anos, o programador COBOL era visto como alguém responsável apenas por arquivos sequenciais, relatórios batch e transações CICS.

JSON GENERATE mudou essa percepção.

Ele permitiu que sistemas escritos décadas atrás começassem a responder chamadas REST, conversar com aplicativos móveis, participar do Open Finance e integrar-se naturalmente a arquiteturas modernas baseadas em APIs.

Talvez essa seja uma das maiores virtudes do Enterprise COBOL.

Ele não exige que o desenvolvedor abandone tudo aquilo que aprendeu.

Ele simplesmente acrescenta novas habilidades.

E diz ao Padawan:

Continue usando seus níveis 01, 05 e 10.

Continue escrevendo programas robustos.

Continue confiando na estabilidade do IBM Z.

Eu apenas ensinarei seu código a responder em uma linguagem compreendida por praticamente toda a galáxia digital.


Continua na Parte 4

JSON Jedi Master – z/OS Connect, MQ, Kafka, OpenShift, APIs de Alto Desempenho, Segurança OWASP e Técnicas Avançadas para o Mestre Bellacosa do IBM Z.

sábado, 7 de setembro de 2024

JSON em COBOL no IBM Z: O Holocron das APIs Modernas – JSON PARSE - Parte II

 

Bellacosa Mainframe e o json no cobol parte II

JSON em COBOL no IBM Z: O Holocron das APIs Modernas

Parte 2 – JSON PARSE

Quando o Padawan Aprende a Transformar Texto em Estruturas COBOL

Por Bellacosa Mainframe


"JSON é apenas texto. O verdadeiro poder está em fazer COBOL compreender esse texto como se fosse uma estrutura nativa do IBM Z."

Mestre Bellacosa Sysprog Jedi


Introdução

Na Parte 1, o Padawan descobriu algo surpreendente.

COBOL moderno fala JSON.

Aprendemos:

  • JSON GENERATE

  • UTF-8

  • CCSID

  • Enterprise COBOL 6.x

  • APIs REST

  • JSON em memória

  • Segurança básica

Agora chegamos ao momento em que o programa COBOL deixa de apenas produzir JSON.

Ele começa a entender JSON.

E isso acontece através de uma instrução quase mágica.

JSON PARSE


O que é JSON PARSE?

JSON PARSE é o tradutor universal.

Ele recebe.

Texto.

Transforma.

Em estruturas COBOL.


Visualmente.

JSON


↓

JSON PARSE


↓

WORKING STORAGE


↓

Programa COBOL

Exemplo.

Recebemos.

{
"id":100,

"nome":"Bellacosa",

"idade":52
}

COBOL deseja.

01 CLIENTE.

05 ID.

PIC 9(5).


05 NOME.

PIC X(30).


05 IDADE.

PIC 999.

JSON PARSE faz isso.

Automaticamente.


Quando surgiu?

IBM introduziu.

JSON PARSE

Enterprise COBOL

Version 6.


Mais utilizado hoje.

6.3

6.4

6.5


Mudou completamente.

Integrações.


Primeiro programa JSON PARSE

Passo 1

Estrutura COBOL

01 WS-CLIENTE.


05 WS-ID.
PIC 9(5).


05 WS-NOME.
PIC X(30).


05 WS-IDADE.
PIC 999.

Passo 2

Buffer JSON

01 WS-JSON.

PIC X(500).

Passo 3

Popular

MOVE

'{"id":100,

"nome":"Bellacosa",

"idade":52}'


TO WS-JSON

Passo 4

Parse

JSON PARSE

WS-JSON

INTO WS-CLIENTE

Passo 5

Display

DISPLAY WS-ID.


DISPLAY WS-NOME.


DISPLAY WS-IDADE.

Resultado.

100


Bellacosa


52

Pronto.

JSON virou COBOL.


O que acontece internamente?

Compilador cria.

Parser interno.


Percorre.

Caractere.

Por caractere.


Reconhece.

Chaves.

Aspas.

Números.

Vetores.


Mapeia.

Campos.


Visualmente.

{


"id"



100



}


↓

COBOL


ID=100

Como funciona na memória?

JSON continua sendo texto.


Exemplo.

Buffer


500 bytes

Parser lê.


Move dados.


Para.

Working Storage.


Resultado.

WS-ID


100



WS-NOME


Bellacosa

Sem ponteiros.

Sem árvore.

Sem DOM.


Muito eficiente.


Objetos Aninhados

JSON suporta.

Estruturas.

Dentro.

De estruturas.


Exemplo.

{

"cliente":{

"id":1,

"nome":"Bellacosa"

}

}

COBOL.

01 CLIENTE.


05 DADOS.


10 ID.


10 NOME.

Muito elegante.


Arrays

Chegamos.

Ao lado divertido.


JSON.

{

"telefones":[

"1111",

"2222"

]

}

COBOL.

05 TELEFONES.

10 TEL OCCURS 10.


15 NUMERO.


PIC X(20).

Parser.

Preenche.


COUNT IN

Muito útil.


Exemplo.

JSON PARSE

WS-JSON


INTO WS-DADOS


COUNT IN WS-CONTADOR

Retorna.

Quantidade.

Itens.


Excelente.

Para.

Arrays.


ON EXCEPTION

Fundamental.

Nunca esquecer.


Exemplo.

JSON PARSE

WS-JSON


INTO WS-CLI


ON EXCEPTION


DISPLAY 'ERRO'

Padawan.

Sempre use.


Exemplo inválido

JSON.

{


"id":100


"nome":"Bellacosa"

Aspa.

Faltando.


Parser.

Falha.


ON EXCEPTION.

Executado.


JSON Malicioso

Poucos falam.

Mas existe.


Payload.

Gigante.


Exemplo.

50 MB.


Consome.

CPU.


Memória.


Tempo.


DoS.


Negação.

Serviço.


Boa prática

Validar.

Tamanho.


Exemplo.

IF WS-LEN > 100000

DISPLAY 'ERRO'

Muito recomendado.


Nomes diferentes

JSON.

Pode vir.

{

"customer_name":"Bellacosa"

}

COBOL.

05 WS-NOME.

Problema.


Precisamos.

Mapear.


Enterprise COBOL possui.

NAME OF.

SUPPRESS.


Falaremos.

Parte 3.


UTF8

Grande inimigo.


JSON.

UTF8.


COBOL.

EBCDIC.


José.

Pode quebrar.


Ç.

Ã.

É.


Atenção.

Sempre.


JSON NULL

JSON.

{


"nome":null
}

COBOL.

Não possui.

Null textual.


Precisamos.

Tratar.


Muito importante.


Performance

Excelente.


JSON PARSE.

É compilado.


Muito rápido.


Melhor.

Que parser.

Manual.


Evite.

UNSTRING


INSPECT


STRING

Desnecessário.


JSON PARSE.

Resolve.


Curiosidades

Muitos bancos.

Recebem.

Milhões.

JSON.

Por dia.


Aplicativos.

PIX.

Cartão.

Open Finance.


Tudo passa.

Por.

JSON.


E em muitos casos.

Existe.

COBOL.

No fim.

Da cadeia.


Debug

Exemplo.

DISPLAY WS-JSON

Muito útil.


Ou.

IBM Debug Tool.


Fault Analyzer.


Dump.


Quando usar?

Excelente.

REST

MQ

Kafka

zOS Connect

Mobile

Open Banking

PIX

Cloud


Quando evitar?

Arquivos internos.


VSAM.


Relatórios.


Batch tradicional.


Bellacosa Best Practices

Sempre

Use ON EXCEPTION


Sempre

Validar tamanho


Sempre

Testar UTF8


Sempre

Documentar JSON


Sempre

Versionar APIs


O Conselho do Mestre Bellacosa

JSON PARSE é provavelmente uma das maiores evoluções já incorporadas ao Enterprise COBOL.

Ele permite que um programa escrito há vinte ou trinta anos compreenda payloads produzidos por smartphones, microsserviços, plataformas OpenShift e aplicações espalhadas pela Internet.

O jovem Padawan deve perceber uma verdade importante.

JSON continua sendo apenas texto.

Mas JSON PARSE transforma esse texto em algo que COBOL entende profundamente.

Estruturas.

Campos.

Vetores.

Níveis.

OCCURS.

Variáveis.

E talvez essa seja a maior beleza do IBM Z moderno.

Ele não exige que o desenvolvedor abandone décadas de conhecimento.

Ele apenas oferece novas ferramentas.

E diz:

Continue programando em COBOL.

Continue usando seus níveis 01, 05 e 10.

Continue confiando em sua experiência.

Eu apenas ensinarei ao seu programa a compreender uma nova linguagem falada por toda a galáxia digital.


Continua na Parte 3

JSON GENERATE – Quando o Padawan Aprende a Construir APIs REST com COBOL, Criar Payloads Elegantes, Controlar Campos, Suprimir Dados e Falar com Microsserviços do Futuro.


quinta-feira, 18 de julho de 2024

JSON em COBOL no IBM Z: O Holocron das APIs Modernas – O Despertar do JSON - Parte I

 

Bellacosa Mainframe e o json no cobol parte I

JSON em COBOL no IBM Z: O Holocron das APIs Modernas

Parte 1 – O Despertar do JSON

Quando o Padawan Descobre que COBOL Pode Falar a Linguagem das APIs

Por Bellacosa Mainframe


"Por décadas, COBOL falou VSAM, DB2, IMS e MQ. Hoje ele também conversa com APIs, microsserviços e nuvens distantes. O idioma escolhido pela galáxia moderna chama-se JSON."

Mestre Bellacosa Sysprog Jedi


Introdução

Durante muitos anos, a vida do desenvolvedor COBOL era relativamente previsível.

Ele acordava.

Abria o ISPF.

Editava um programa.

Fazia um READ em um VSAM.

Consultava um DB2.

Chamava um CICS.

Enviava uma mensagem MQ.

Executava o JOB.

Analisava o SDSF.

E ia tomar café.

Então, por volta da década de 2010, uma nova criatura começou a aparecer nas especificações técnicas.

Ela vinha acompanhada de nomes estranhos.

REST.

OpenAPI.

Swagger.

Microservices.

Kubernetes.

OpenShift.

APIs.

Mobile.

Cloud.

E no meio de tudo isso, um pequeno formato textual se tornou praticamente o idioma universal da integração moderna.

Seu nome era:

JSON

(JavaScript Object Notation)

E então o jovem Padawan COBOL perguntou:

Mestre...

Quer dizer que meu programa COBOL de 30 anos pode conversar com um aplicativo Android?

Pode responder uma API REST?

Pode enviar dados para um microsserviço em OpenShift?

Pode participar de uma arquitetura moderna?

O mestre sorri.

Olha para o IBM z17.

E responde:

Sim.

E o idioma utilizado para essa conversa provavelmente será JSON.


O que é JSON?

JSON significa:

JavaScript Object Notation.

Mas não se deixe enganar pelo nome.

Hoje JSON pertence ao mundo inteiro.

Não é apenas JavaScript.

É utilizado por:

  • COBOL

  • Java

  • Python

  • Go

  • Rust

  • Node.js

  • C#

  • Kotlin

  • Swift

  • APIs REST

  • OpenShift

  • Kafka

  • IBM MQ

  • z/OS Connect

Praticamente tudo.


Exemplo simples

Um cliente.

Em COBOL.

Temos:

01 WS-CLIENTE.

   05 WS-ID.

      PIC 9(5).

   05 WS-NOME.

      PIC X(30).

   05 WS-IDADE.

      PIC 999.

Em JSON.

{
  "id":100,
  "nome":"Bellacosa",
  "idade":52
}

Mesmo dado.

Representações diferentes.


Por que JSON venceu XML?

Muitos veteranos perguntam:

Mestre...

Mas XML não fazia isso antes?

Sim.

Fazia.

E ainda faz.

Mas JSON trouxe algumas vantagens.


XML

<cliente>

<id>100</id>

<nome>Bellacosa</nome>

</cliente>

JSON

{
"id":100,
"nome":"Bellacosa"
}

Menor.

Mais leve.

Mais rápido.

Mais amigável.


JSON chegou tarde ao COBOL?

Sim.

Durante muitos anos, programadores precisavam utilizar:

Parsers.

Ferramentas externas.

Java.

C.

SAX.

DOM.

Bibliotecas proprietárias.

Era desagradável.


Quando surgiu suporte nativo?

IBM introduziu suporte moderno em:

Enterprise COBOL V6

Especialmente.

COBOL 6.1

6.2

6.3

6.4

6.5


Duas instruções mudaram tudo.

JSON PARSE

JSON GENERATE

Essas duas instruções transformaram COBOL em um cidadão de primeira classe no universo das APIs.


O que é JSON PARSE?

É o tradutor.

Recebe texto.

Produz estruturas COBOL.


Visualmente.

JSON


↓

JSON PARSE


↓

WORKING STORAGE

O que é JSON GENERATE?

Faz o contrário.

WORKING STORAGE


↓

JSON GENERATE


↓

Texto JSON

Primeiro exemplo do Padawan

Passo 1

Criar estrutura.

01 WS-CLIENTE.

   05 WS-ID.

      PIC 9(5).

   05 WS-NOME.

      PIC X(30).

   05 WS-IDADE.

      PIC 999.

Passo 2

Criar buffer.

01 WS-JSON.

PIC X(200).

Passo 3

Popular dados.

MOVE 100

TO WS-ID


MOVE 'BELLACOSA'

TO WS-NOME


MOVE 52

TO WS-IDADE

Passo 4

Gerar JSON.

JSON GENERATE WS-JSON

FROM WS-CLIENTE

Passo 5

Display.

DISPLAY WS-JSON

Resultado.

{
"id":100,
"nome":"BELLACOSA",
"idade":52
}

Pronto.

COBOL falando JSON.


Como funciona internamente?

Aqui começa a magia.

O compilador gera código otimizado.

Percorre estrutura COBOL.

Mapeia campos.

Converte.

Monta texto.

Tudo automaticamente.


Visualmente.

WORKING STORAGE


↓

Field Scanner


↓

Serializer


↓

UTF-8


↓

JSON Buffer

Como JSON fica na memória?

JSON é texto.

Normalmente.

UTF-8.


Exemplo.

{"nome":"Bellacosa"}

Na memória.

7B

22

6E

6F

6D

65

Bytes.


CCSID

Muito importante.

Padawan frequentemente esquece.

IBM Z trabalha com:

EBCDIC.

JSON trabalha com:

UTF-8.


Complicação.


Exemplo.

COBOL.

EBCDIC

API.

UTF8

Conversão necessária.


Exemplo

Nome.

José


UTF8.

Dois bytes.


EBCDIC.

Outro código.


Pode quebrar.


Segurança

Muito importante.

JSON pode ser perigoso.


Exemplo.

Payload enorme.

{
"clientes":[

100000 itens

]
}

Pode consumir.

CPU.

Memória.

Tempo.


Boa prática.

Validar tamanho.


JSON Injection

Também existe.


Nunca confiar.

Em entrada.

Externa.


Sempre validar.


Arrays

JSON suporta.

{
"clientes":[

{"id":1},

{"id":2}

]
}

COBOL.

OCCURS.


Excelente integração.


Objetos aninhados

{
"cliente":{

"id":1,

"endereco":{

"cidade":"SP"

}

}
}

COBOL.

Níveis.


Muito elegante.


Curiosidade

JSON PARSE.

Não cria ponteiros.

Não cria DOM.

Não cria árvore.


Preenche estruturas COBOL.

Diretamente.


Extremamente eficiente.


Performance

Muito boa.


JSON GENERATE.

É rápido.


Muito mais rápido.

Do que escrever.

String manualmente.


Exemplo ruim.

STRING

'{'

'"nome":"'

WS-NOME

'"'

'}'

Terrível.


JSON GENERATE.

Melhor.


Quando usar?

Excelente para.


APIs.

REST.

MQ.

Kafka.

OpenShift.

Mobile.

Cloud.

Microsserviços.


Quando evitar?


Arquivos internos.

VSAM.

Batch puro.

Relatórios.


Curiosidade Bellacosa

Muitos programas COBOL modernos já trabalham com JSON diariamente.

E boa parte dos usuários finais jamais imagina.

Ao abrir um aplicativo bancário.

Consultar saldo.

Fazer PIX.

Solicitar empréstimo.

Atualizar cadastro.

Frequentemente existe um programa COBOL recebendo JSON silenciosamente em algum lugar do IBM Z.


O Conselho do Mestre Bellacosa

Durante décadas, COBOL foi visto como uma linguagem presa a cartões perfurados, arquivos sequenciais e relatórios impressos.

JSON mudou essa percepção.

JSON permitiu que programas escritos há décadas conversassem com aplicações móveis, microsserviços em OpenShift, APIs em nuvem e plataformas digitais espalhadas pela galáxia tecnológica.

E talvez essa seja a maior lição desta primeira jornada.

COBOL não precisou deixar de ser COBOL.

Não precisou abandonar sua robustez.

Não precisou reescrever milhões de linhas.

Ele simplesmente aprendeu um novo idioma.

E hoje pode dizer:

Eu ainda sou COBOL.

Ainda processo milhões de transações por segundo.

Ainda executo no IBM Z.

Mas agora também falo JSON.

E posso conversar com praticamente qualquer sistema da galáxia.


Continua na Parte 2

JSON PARSE – Transformando Texto em Estruturas COBOL: Arrays, Objetos Aninhados, OCCURS, Tratamento de Erros e o Lado Sombrio dos Payloads Maliciosos.


quinta-feira, 14 de dezembro de 2023

🧪 SENKU E A DUNGEON DOS FUNDAMENTOS — QUANDO O PROGRAMADOR COBOL DESCOBRIU QUE O IF TINHA BILHÕES DE TRANSISTORES ESCONDIDOS

 

Bellacosa Mainframe e fundamentos da informatica

☕ Um Café no Bellacosa Mainframe

🧪 SENKU E A DUNGEON DOS FUNDAMENTOS — QUANDO O PROGRAMADOR COBOL DESCOBRIU QUE O IF TINHA BILHÕES DE TRANSISTORES ESCONDIDOS

CPU, ALU, registradores, memória, cache, binário, hexadecimal, EBCDIC, sistemas operacionais, redes, bancos de dados, SQL, virtualização, cloud, containers — e o dia em que Senku Ishigami decidiu reconstruir a Ciência da Computação, uma abstração de cada vez.



🎬 PRÓLOGO — DEZ BILHÕES POR CENTO CERTEZA DE QUE NÃO É MAGIA

Imagine a situação.

Você acabou de entrar no mundo do mainframe.

Aprendeu seus primeiros comandos COBOL:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PEDRA001.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01 WS-SALDO       PIC 9(7)V99 VALUE 1000.00.
       01 WS-COMPRA      PIC 9(7)V99 VALUE 150.00.

       PROCEDURE DIVISION.

           IF WS-SALDO >= WS-COMPRA
               DISPLAY 'COMPRA AUTORIZADA'
           ELSE
               DISPLAY 'SALDO INSUFICIENTE'
           END-IF.

           STOP RUN.

Compilou.

Executou.

Funcionou.

Você olha para a tela e pensa:

“Entendi. O computador comparou dois números.”

Nesse momento, Senku Ishigami, de Dr. Stone, provavelmente apareceria carregando alguma engenhoca feita com pedras, fios, ácido sulfúrico e uma quantidade suspeita de confiança científica.

— Errado!

Não porque o programa esteja errado.

Mas porque entre:

IF WS-SALDO >= WS-COMPRA

e:

COMPRA AUTORIZADA

existe uma civilização inteira.

CPU.

Registradores.

Cache.

RAM.

Sistema operacional.

Memória virtual.

Encoding.

Storage.

Compilador.

Instruções de máquina.

Talvez Db2.

Talvez CICS.

Talvez MQ.

Talvez TCP/IP.

Talvez uma API.

Talvez outro computador do outro lado do planeta.

A melhor maneira de entender fundamentos de computação, portanto, não é decorar vinte definições para uma prova.

É fazer algo muito mais próximo da filosofia de Dr. Stone:

reconstruir o computador conceitualmente, camada por camada.

Pegue uma pedra.

Depois outra.

Depois eletricidade.

Depois lógica.

Depois memória.

Depois software.

Quando terminarmos nossa dungeon, aquela pequena instrução COBOL nunca mais parecerá tão pequena.



🪨 CAPÍTULO 1 — ANTES DO COBOL EXISTIA A PEDRA

Vamos começar do absoluto zero.

O que é um computador?

Uma definição introdutória bastante útil seria:

Um computador é uma máquina eletrônica programável capaz de receber dados, processá-los, armazená-los e produzir resultados.

Temos então:

INPUT
  ↓
PROCESSING
  ↓
OUTPUT
  ↓
STORAGE

Um teclado fornece entrada.

A CPU processa.

Um monitor apresenta saída.

Um dispositivo de armazenamento preserva dados.

Essa explicação funciona.

Mas Senku provavelmente perguntaria:

— O que significa processar?

E aí começa nossa aventura.

Processar significa transformar um estado em outro seguindo regras.

Considere:

SALDO = 1000
COMPRA = 150

O computador recebe esses valores e executa determinada transformação.

Depois:

SALDO = 850

Nada disso possui significado financeiro para a CPU.

Para ela não existem:

clientes, salários, boletos, cartões, parcelas ou financiamento.

Existem representações.

Nós, humanos, construímos significado em cima delas.

Essa diferença entre dado e informação é importante.

Considere:

80
90
70

São dados.

Quando aplicamos uma regra:

(80 + 90 + 70) / 3 = 80

produzimos algo interpretável:

MÉDIA = 80

O processamento transformou dados em informação útil dentro de determinado contexto.

É exatamente isso que sistemas empresariais fazem bilhões de vezes.



⚡ CAPÍTULO 2 — SENKU DESCOBRE O BIT

Precisamos agora construir nosso computador.

Infelizmente ainda não temos COBOL.

Nem Windows.

Nem z/OS.

Nem sequer uma CPU.

Temos eletricidade.

Precisamos representar informação fisicamente.

Uma solução extraordinariamente poderosa é trabalhar com dois estados.

Conceitualmente:

0
1

Nasce o bit, abreviação de binary digit.

Um bit pode representar duas possibilidades.

Com dois bits:

00
01
10
11

temos quatro combinações.

Com três:

000
001
010
011
100
101
110
111

oito combinações.

A fórmula geral é:

2ⁿ

Com 8 bits:

2⁸ = 256

combinações possíveis.

Oito bits formam convencionalmente um byte.

Agora já podemos representar números.



🔢 CAPÍTULO 3 — O PROGRAMADOR COBOL ENTRA NA DUNGEON DO BINÁRIO

Nós utilizamos normalmente base decimal:

347

Na verdade isso significa:

3 × 10² +
4 × 10¹ +
7 × 10⁰

ou:

300 + 40 + 7

Binário funciona exatamente da mesma maneira, apenas utilizando base 2.

Considere:

1011₂

Temos:

1 × 2³ = 8
0 × 2² = 0
1 × 2¹ = 2
1 × 2⁰ = 1

Portanto:

1011₂ = 11₁₀

Não há magia.

É apenas um sistema posicional com outra base.



🧙 CAPÍTULO 4 — SURGE O HEXADECIMAL

Imagine analisar:

110101101101101111101111

Depois de algumas horas, até Senku pediria café.

Por isso hexadecimal é tão conveniente.

Ele utiliza base 16:

0 1 2 3 4 5 6 7 8 9 A B C D E F

A grande vantagem é:

um dígito hexadecimal representa exatamente quatro bits.

Assim:

1111₂ = F₁₆

E:

11111111₂ = FF₁₆

Para um programador mainframe, hexadecimal não é apenas matéria escolar.

Quando começamos a analisar dumps, campos, bytes e problemas de dados, ele pode se transformar numa ferramenta cotidiana.

Dica de Padawan COBOL:

aprenda hexadecimal antes de precisar dele em produção às 03:17.

Sim, 03:17.

Guarde esse horário.

Toda dungeon precisa de um easter egg.


🧪 CAPÍTULO 5 — CPU: O LABORATÓRIO DE SENKU

Agora precisamos de algo capaz de executar operações.

Chegamos à CPU — Central Processing Unit.

Materiais introdutórios normalmente apresentam três componentes conceituais:

CPU
├── ALU
├── Control Unit
└── Registers

A ALU — Arithmetic and Logic Unit executa operações aritméticas e lógicas.

Exemplos:

+
-
*
/
AND
OR
NOT
>
<
=

A Control Unit coordena a execução das instruções.

Os registradores são pequenas áreas de armazenamento extremamente rápidas dentro do processador.

Podemos imaginar o ciclo clássico:

FETCH
 ↓
DECODE
 ↓
EXECUTE
 ↓
FETCH...

Primeiro a CPU busca uma instrução.

Depois descobre o que aquela instrução significa.

Finalmente executa a operação correspondente.

É uma simplificação, naturalmente.

Processadores modernos possuem pipelines, múltiplas unidades de execução, predição de desvios, execução especulativa e inúmeros outros mecanismos.

Mas nosso modelo é excelente para começar.


🧮 CAPÍTULO 6 — A ALU NÃO SABE O QUE É DINHEIRO

Aqui aparece algo fascinante para quem vem do COBOL.

Considere:

01 WS-PRECO PIC S9(7)V99 COMP-3.

COMP-3 indica uma representação decimal compactada (packed decimal).

Por que isso interessa?

Porque computadores são naturalmente excelentes em binário, enquanto aplicações comerciais frequentemente precisam lidar cuidadosamente com decimal.

Dinheiro é o exemplo clássico.

Em algumas representações de ponto flutuante binário, valores decimais aparentemente simples não possuem representação exata.

Para aplicações científicas isso pode ser perfeitamente administrável.

Mas:

R$ 1.000.000,00

não é o tipo de número no qual o banco gostaria de descobrir um centavo filosófico surgido por aproximação.

A computação empresarial desenvolveu durante décadas mecanismos especializados para aritmética decimal.

COBOL está profundamente ligado a essa história.


🏎️ CAPÍTULO 7 — REGISTRADORES, CACHE, RAM E A CORRIDA PELA MEMÓRIA

A CPU é extremamente rápida.

Mas existe um problema:

buscar dados custa tempo.

Por isso computadores possuem uma hierarquia de memória.

Simplificando:

        REGISTRADORES
             ↓
            L1
             ↓
            L2
             ↓
            L3
             ↓
            RAM
             ↓
         SSD / DASD
             ↓
      armazenamento remoto

Quanto mais próximo da CPU, normalmente temos:

mais velocidade
menos capacidade
maior custo por byte

Quanto mais distante:

mais capacidade
maior latência
menor custo relativo

A cache explora principalmente duas propriedades muito interessantes dos programas.

Localidade temporal

Se você acabou de utilizar determinado dado, talvez precise dele novamente.

Localidade espacial

Se acessou determinado endereço, provavelmente poderá acessar dados próximos.

Considere:

PERFORM VARYING WS-I FROM 1 BY 1
    UNTIL WS-I > 100000
       ADD WS-VALOR(WS-I) TO WS-TOTAL
END-PERFORM.

O acesso sequencial pode apresentar comportamento bastante favorável à hierarquia de memória.

Isso nos ensina algo importante:

performance não depende somente do número de linhas do programa.

O modo como acessamos memória e dados importa.


💾 CAPÍTULO 8 — RAM NÃO É DISCO

Outra confusão comum entre iniciantes:

“Meu computador tem 16 GB de memória e 1 TB de memória.”

Não exatamente.

Os 16 GB provavelmente são RAM.

O 1 TB provavelmente corresponde ao armazenamento persistente.

RAM é memória de trabalho, normalmente volátil.

SSD, HDD ou armazenamento empresarial preservam dados de maneira persistente.

No mundo mainframe podemos pensar em:

DASD
  ↓
DATASET
  ↓
BUFFER
  ↓
MEMÓRIA
  ↓
CACHE
  ↓
CPU

Quando seu COBOL escreve:

READ ARQ-CLIENTES

parece que o programa simplesmente “leu o arquivo”.

Mas entre a instrução e o dado podem existir várias camadas de software, memória, buffers, cache, canais e armazenamento.

A simplicidade do COBOL é construída sobre uma enorme complexidade escondida.


🏰 CAPÍTULO 9 — SISTEMA OPERACIONAL: O SENKU DOS RECURSOS

Chegamos ao sistema operacional.

Ele administra recursos como:

CPU
memória
processos
arquivos
dispositivos
segurança
usuários
I/O

Mas sua função intelectualmente mais interessante talvez seja outra:

criar abstrações.

Você diz:

ARQUIVO

O sistema operacional esconde inúmeros detalhes físicos.

Você diz:

PROCESSO

Ele administra execução, memória e recursos.

Você pensa:

MEMÓRIA

Por baixo podem existir mecanismos sofisticados de memória virtual e tradução de endereços.

É como se o sistema operacional dissesse:

“Programador, cuide do seu problema. Eu cuido desta dungeon.”

No universo IBM Z encontramos um caso extraordinariamente rico:

IBM Z
 │
PR/SM
 │
LPAR
 │
z/OS

E podemos ter múltiplas partições executando diferentes workloads e sistemas.

A virtualização não nasceu com a cloud.

O universo mainframe possui uma história de virtualização que antecede em décadas boa parte da terminologia moderna de infraestrutura.


👻 CAPÍTULO 10 — SENKU ENCONTRA O FANTASMA DO EBCDIC

Agora precisamos representar letras.

Um computador não armazena conceitualmente a letra:

A

Ele armazena uma representação numérica interpretada segundo determinada codificação.

Em ASCII:

A = 0x41

Em páginas EBCDIC comuns:

A = 0xC1

E aqui encontramos uma criatura muito conhecida da dungeon mainframe:

EBCDIC

Extended Binary Coded Decimal Interchange Code.

Quem trabalha apenas com sistemas distribuídos modernos pode passar anos praticamente sem pensar nele.

Quem integra mainframe com outros ambientes eventualmente descobre sua existência.

Imagine:

COBOL / EBCDIC
       ↓
      MQ
       ↓
 integração
       ↓
 JSON / UTF-8
       ↓
 aplicação web

Se as conversões forem incorretas, aparecem caracteres aparentemente misteriosos.

Não foi um espírito.

Não foi RACF.

Não foi CICS possuído.

Pode simplesmente ser encoding.

Dica prática:

quando dados textuais atravessarem plataformas diferentes, pergunte sempre qual é a codificação na origem e qual é a codificação no destino.


🌐 CAPÍTULO 11 — SENKU INVENTA A REDE

Temos computadores.

Agora queremos conectá-los.

Podemos encontrar classificações tradicionais:

PAN
LAN
MAN
WAN

Mas compreender redes exige ir além da distância geográfica.

Imagine camadas:

APLICAÇÃO
HTTP / DNS
────────────
TRANSPORTE
TCP / UDP
────────────
REDE
IP
────────────
ENLACE
Ethernet
────────────
FÍSICA
sinais

Quando alguém escreve:

https://exemplo.com

pode ocorrer uma cadeia aproximadamente assim:

nome
 ↓
DNS
 ↓
endereço IP
 ↓
roteamento
 ↓
TCP
 ↓
TLS
 ↓
HTTP
 ↓
aplicação

Agora imagine um programa COBOL CICS expondo funcionalidade por uma API.

De repente:

COBOL

está conversando conceitualmente com:

HTTP
JSON
TLS
TCP/IP

O programa de 30 anos não precisou necessariamente virar JavaScript para participar da Internet.

Essa é uma lição importantíssima sobre modernização:

integrar não significa obrigatoriamente reescrever.


🗄️ CAPÍTULO 12 — O REINO DOS BANCOS DE DADOS

Precisamos armazenar dados organizadamente.

Chegamos aos bancos de dados.

Primeira distinção:

DATABASE ≠ DBMS

O banco contém dados organizados.

O DBMS — Database Management System é o software responsável por gerenciá-los.

Em um banco relacional encontramos conceitos como:

TABLE
ROW
COLUMN
PRIMARY KEY
FOREIGN KEY

Mas um DBMS moderno faz muito mais:

transações
locking
logging
recovery
índices
buffers
segurança
concorrência
otimização
integridade

No mundo mainframe, Db2 é um personagem importantíssimo dessa história.


💰 CAPÍTULO 13 — SENKU TENTA FAZER UMA TRANSFERÊNCIA BANCÁRIA

Suponha:

CONTA A = 1000
CONTA B = 500

Queremos transferir 100.

Precisamos:

A = A - 100
B = B + 100

Mas imagine:

A = A - 100

*** SISTEMA CAI ***

E a segunda operação nunca acontece.

Parabéns.

Inventamos uma máquina de desaparecer dinheiro.

Por isso sistemas transacionais precisam de propriedades robustas.

Surge a famosa ideia de ACID:

Atomicity
Consistency
Isolation
Durability

Atomicidade significa, de forma simplificada:

a transação deve ser tratada como uma unidade — não queremos metade lógica da operação confirmada e metade perdida.

Isso é central para compreender sistemas empresariais.

CICS, Db2 e outros componentes do ecossistema transacional não existem apenas para tornar a arquitetura mais bonita em PowerPoint.

Eles existem porque dinheiro, estoque, reservas e pagamentos não toleram facilmente:

“quase funcionou”.

📜 CAPÍTULO 14 — SQL DESCOBRE UMA MAGIA DIFERENTE DO COBOL

COBOL é predominantemente procedural.

Você escreve uma sequência de ações.

SQL possui natureza declarativa.

Considere:

SELECT NOME, SALDO
FROM CLIENTES
WHERE CIDADE = 'ITATIBA';

Você informou o resultado desejado.

Não necessariamente determinou fisicamente:

abra o arquivo
leia registro
compare cidade
avance
leia novamente
...

O DBMS possui um otimizador.

Ele pode escolher diferentes estratégias.

Por exemplo:

table scan
index access
join
sort

Essa é uma mudança profunda de pensamento.

COBOL frequentemente pergunta:

COMO devo fazer?

SQL frequentemente permite dizer:

O QUE quero obter?

O DBMS procura uma estratégia.

Essa diferença entre programação procedural e declarativa reaparece em muitos outros lugares da computação moderna.


☁️ CAPÍTULO 15 — SENKU OLHA PARA O CÉU E NÃO ENCONTRA A CLOUD

Cloud computing é frequentemente explicada como:

recursos computacionais disponíveis pela Internet.

É um começo.

Mas se fosse somente isso, qualquer servidor remoto dos anos 1990 poderia receber retroativamente um adesivo escrito CLOUD.

O conceito moderno envolve características operacionais importantes:

provisionamento sob demanda
automação
elasticidade
resource pooling
medição de consumo
self-service

Portanto:

CLOUD ≠ COMPUTADOR DE OUTRA PESSOA

Essa piada possui alguma utilidade, mas é insuficiente tecnicamente.

Cloud é também um modelo operacional.

Isso nos leva a uma conexão interessante com mainframe.

Mainframes já praticavam há décadas ideias relacionadas a:

compartilhamento de recursos
virtualização
isolamento
gestão de workload
alta utilização
automação

Cloud não transformou o mainframe numa relíquia.

Na realidade, estudar mainframe ajuda a perceber que várias ideias consideradas modernas possuem ancestrais bastante antigos.


📦 CAPÍTULO 16 — CONTAINER NÃO É UMA VM EMAGRECIDA

Outra confusão clássica.

Máquinas virtuais e containers trabalham com isolamento, mas em níveis diferentes.

Simplificando uma VM:

APLICAÇÃO
   ↓
GUEST OS
   ↓
HYPERVISOR
   ↓
HARDWARE

Agora um container:

APLICAÇÃO
DEPENDÊNCIAS
   ↓
CONTAINER RUNTIME
   ↓
HOST OS
   ↓
HARDWARE

Containers normalmente compartilham recursos do kernel do host em vez de carregar necessariamente um sistema operacional convidado completo para cada instância.

Por isso podem ser leves e rápidos de iniciar.

Mas existe um detalhe importante:

containers e VMs podem coexistir.

Podemos ter:

HARDWARE
   ↓
VIRTUAL MACHINE
   ↓
LINUX
   ↓
CONTAINER RUNTIME
   ↓
CONTAINER

Tecnologia raramente é simplesmente:

VELHO ❌
NOVO ✅

Muito mais frequentemente encontramos:

camada
sobre
camada
sobre
camada.

🧠 CAPÍTULO 17 — SENKU DESCOBRE O VERDADEIRO SEGREDO: ABSTRAÇÃO

Finalmente chegamos ao conceito que une praticamente tudo.

Abstração.

Observe:

APLICAÇÃO
     ↓
COBOL
     ↓
COMPILADOR / RUNTIME
     ↓
MIDDLEWARE
     ↓
SISTEMA OPERACIONAL
     ↓
MEMÓRIA
     ↓
CPU
     ↓
MICROARQUITETURA
     ↓
CIRCUITOS
     ↓
TRANSISTORES
     ↓
FÍSICA

Cada camada permite esquecer temporariamente detalhes da camada inferior.

Sem isso seria praticamente impossível desenvolver sistemas modernos.

Imagine escrever:

DISPLAY 'BOM DIA'.

e precisar manualmente definir:

pixels
buffers
endereços físicos
sinais elétricos
registradores
temporização
I/O

Nunca terminaríamos o sistema.

Abstração é o mecanismo pelo qual transformamos complexidade inadministrável em conceitos utilizáveis.

Mas existe uma regra que todo profissional experiente aprende:

quando a abstração quebra, desça uma camada.


⚔️ CAPÍTULO 18 — O JOB LEVAVA 4 MINUTOS. AGORA LEVA 38.

Chegamos à War Room.

Produção informa:

ONTEM: 4 minutos
HOJE: 38 minutos

O programador iniciante abre imediatamente o COBOL.

Isso não é absurdo.

Pode realmente existir algum problema no programa.

Mas o profissional mais experiente constrói hipóteses.

O volume aumentou?

Mudou o access path do Db2?

Existe mais I/O?

Algum índice mudou?

Há contenção?

Existe locking?

O SORT cresceu?

Mudou o workload concorrente?

Há pressão de CPU?

A memória está pressionada?

Storage está respondendo diferente?

Alguma alteração foi implantada?

O programa está esperando alguma coisa?

Observe a mudança.

O iniciante pensa:

PROGRAMA → PROBLEMA

O engenheiro pensa:

SISTEMA
├── aplicação
├── dados
├── banco
├── middleware
├── sistema operacional
├── rede
├── CPU
├── memória
└── storage

Isso não significa investigar tudo indiscriminadamente.

Significa formular hipóteses e procurar evidências.

Senku aprovaria.

Ciência antes de superstição.


🏛️ CAPÍTULO 19 — O IBM Z COMO LABORATÓRIO DE FUNDAMENTOS

Agora podemos reunir nossa dungeon.

Imagine:

                    IBM Z
                      │
                    PR/SM
                      │
                    LPAR
                      │
                    z/OS
                      │
          ┌───────────┼───────────┐
          │           │           │
         JES         WLM         RACF
          │           │           │
          └───────────┼───────────┘
                      │
          ┌───────────┼───────────┐
          │           │           │
        CICS         Db2          MQ
          │           │           │
          └───────────┼───────────┘
                      │
                    COBOL

Essa representação é propositalmente simplificada, mas revela algo fundamental.

COBOL não é uma ilha.

Quando você aprende apenas sintaxe COBOL, aprende uma camada.

Quando entende:

JCL
datasets
VSAM
Db2
CICS
MQ
JES
RACF
WLM
TCP/IP
z/OS
storage
CPU

começa a enxergar o sistema.

E existe uma enorme diferença entre:

saber escrever um programa

e:

entender o sistema no qual o programa vive.


🧭 CAPÍTULO 20 — ROTEIRO DO PADAWAN: COMO ESTUDAR TUDO ISSO SEM ENLOUQUECER

Não tente aprender tudo simultaneamente.

Construa a civilização como Senku.

Etapa 1 — representação

Aprenda:

bit
byte
binário
hexadecimal
caracteres
ASCII
EBCDIC
Unicode
UTF-8

Faça conversões simples à mão.

Entenda por que:

41

pode significar coisas completamente diferentes dependendo de como interpretamos os bits.

Etapa 2 — hardware

Estude:

CPU
ALU
registradores
cache
RAM
storage
I/O

Não precisa projetar um processador.

Precisa entender onde os dados estão e por que movimentá-los custa tempo.

Etapa 3 — sistema operacional

Entenda:

processo
memória
arquivo
I/O
segurança
virtualização

Depois traduza isso para z/OS.

Etapa 4 — COBOL

Agora:

PIC
MOVE
COMPUTE
IF
EVALUATE
PERFORM
READ
WRITE
CALL

começam a ganhar contexto.

Etapa 5 — dados

Estude:

QSAM
VSAM
Db2
SQL
transações
índices
commit
rollback

Etapa 6 — processamento empresarial

Entre em:

batch
JCL
JES
CICS
Db2
MQ

Etapa 7 — integração

Finalmente:

TCP/IP
HTTP
REST
JSON
APIs
mensageria
cloud
containers

Agora o mainframe deixa de parecer uma máquina isolada e passa a aparecer como aquilo que realmente é:

uma plataforma participante de arquiteturas empresariais muito maiores.


🔬 CAPÍTULO 21 — TRÊS EXPERIMENTOS DE SENKU PARA O PROGRAMADOR COBOL

Faça estes pequenos laboratórios.

Experimento 1 — Hexadecimal. Pegue caracteres como A, 0, espaço e compare suas representações em ASCII e EBCDIC. Depois imagine o que aconteceria se um sistema interpretasse bytes EBCDIC como ASCII.

Você compreenderá encoding melhor do que decorando definições.

Experimento 2 — SQL. Compare mentalmente:

PERFORM UNTIL EOF
    READ CLIENTES
    IF CIDADE = 'ITATIBA'
       DISPLAY NOME
    END-IF
END-PERFORM

com:

SELECT NOME
FROM CLIENTES
WHERE CIDADE = 'ITATIBA';

Pergunte:

quem decidiu como encontrar os registros?

A resposta revela a diferença entre procedural e declarativo.

Experimento 3 — performance. Quando um programa estiver lento, não pergunte imediatamente:

“Qual linha está lenta?”

Pergunte primeiro:

“Onde o tempo está sendo gasto?”

Essas duas perguntas parecem semelhantes.

Não são.


🗿 CAPÍTULO 22 — A CURIOSIDADE ESCONDIDA NA PEDRA

Existe uma ironia histórica deliciosa.

Cada geração acredita ter inventado completamente o futuro.

Virtualização parece moderna.

Computação distribuída parece moderna.

Cloud parece moderna.

Containers parecem modernos.

Inteligência Artificial parece ter surgido ontem.

Mas a computação é uma enorme árvore genealógica.

Ideias reaparecem modificadas.

Problemas antigos recebem novas abstrações.

Tecnologias desaparecem e seus conceitos sobrevivem.

É exatamente por isso que estudar fundamentos continua valendo a pena.

Uma ferramenta pode desaparecer.

Um framework pode desaparecer.

Uma linguagem pode perder popularidade.

Mas conceitos como:

estado
memória
I/O
transação
concorrência
representação
abstração
algoritmo
protocolo
persistência

continuam retornando com roupas diferentes.


☕ EPÍLOGO — O IF DE DUAS LINHAS QUE CARREGA UM SÉCULO DE CIÊNCIA

Voltamos finalmente ao nosso pequeno programa:

IF WS-SALDO >= WS-COMPRA
    DISPLAY 'COMPRA AUTORIZADA'
END-IF.

Agora você sabe que essas duas linhas escondem uma cadeia extraordinária.

O fonte COBOL precisa ser representado por caracteres.

Os caracteres precisam possuir encoding.

O compilador precisa compreender a linguagem.

O programa precisa transformar-se em algo executável pela arquitetura.

O sistema operacional precisa fornecer recursos.

Dados precisam ocupar memória.

A CPU precisa executar instruções.

Registradores e caches participam do processamento.

Talvez o saldo venha do Db2.

Talvez a transação esteja sob CICS.

Talvez uma mensagem atravesse MQ.

Talvez outra plataforma participe pela rede.

Talvez o resultado seja entregue por uma API para um smartphone a milhares de quilômetros do datacenter.

O usuário toca:

COMPRAR

e espera talvez dois segundos.

Ele não quer saber de:

CPU
cache
RAM
EBCDIC
SQL
Db2
CICS
TCP/IP
TLS
MQ
storage

E está certo.

Essa complexidade é problema nosso.

Essa é a beleza da engenharia.

Construímos uma camada para que a próxima possa esquecer a anterior.

Até que um dia algo quebra.

Às 03:17.

O telefone toca.

A aplicação não responde.

O programador olha para o COBOL e diz:

“Mas meu IF está correto!”

Então Senku aparece imaginariamente na War Room, pega o café abandonado ao lado do terminal 3270 e responde:

Então formule outra hipótese.

Esse talvez seja o ensinamento mais importante de todos os fundamentos de computação.

Não decore simplesmente que CPU significa Central Processing Unit.

Não decore que RAM é volátil.

Não decore que DNS converte nomes em endereços.

Não decore que SQL consulta bancos.

Não decore que cloud fornece recursos.

Pergunte por quê.

Pergunte o que existe abaixo.

Pergunte qual abstração está escondendo qual complexidade.

Pergunte onde o dado nasceu, como foi representado, onde foi armazenado, como chegou até a CPU, quem o modificou, como foi persistido e como atravessou a rede.

Porque o dia em que um programador COBOL começa a enxergar:

COBOL
   ↓
CICS / Db2 / MQ
   ↓
z/OS
   ↓
virtualização
   ↓
CPU / memória / I/O
   ↓
hardware

é o dia em que deixa de enxergar somente programas.

Começa a enxergar sistemas.

E esse é um upgrade que nenhum MOVE, PERFORM ou certificado consegue fornecer sozinho.

Senku começou sua reconstrução com pedras, ciência e perguntas.

Nosso Padawan começa com:

IDENTIFICATION DIVISION.

O destino, porém, é muito parecido:

entender como as coisas realmente funcionam.

E quando alguém perguntar se precisamos mesmo conhecer binário, hexadecimal, CPU, memória, sistema operacional, banco de dados, redes, virtualização e cloud para programar COBOL, já temos a resposta.

Para escrever:

DISPLAY 'HELLO'.

provavelmente não.

Para descobrir por que o HELLO não apareceu às 03:17 da madrugada?

Aí começa a verdadeira Ciência da Computação.

Dez bilhões por cento.

Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...