MySQL
Código: Selecionar todos
CREATE FUNCTION ze_ValidCNPJ( cCnpj VARCHAR(20) )
RETURNS int(11)
BEGIN
DECLARE cNumero VARCHAR(20);
DECLARE lOk INT(11);
SET cNumero = ze_SoNumeroCnpj( cCnpj );
IF LENGTH( cNumero ) <> 14 THEN
RETURN IF( LENGTH( cNumero ) = 0, 1, 0 );
END IF;
SET cNumero = LPAD( cNumero, 14, '0' );
SET cNumero = SUBSTR( cNumero, 1, 12 );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 11 ) );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 11 ) );
SET lOk = ( Right( cCnpj, 2 ) = Right( cNumero, 2 ) );
IF lOk THEN
SET cCnpj = CONCAT( SUBSTR( cNumero, 1, 2 ), '.',
SUBSTR( cNumero, 3, 3 ), '.',
SUBSTR( cNumero, 6, 3 ), '/',
SUBSTR( cNumero, 9, 4 ), '-',
SUBSTR( cNumero, 13, 2 ) );
END IF;
RETURN lOk;
END
Código: Selecionar todos
CREATE FUNCTION ze_SoNumeroCnpj( cValue TEXT )
RETURNS TEXT CHARSET latin1
BEGIN
DECLARE cNewValue TEXT;
DECLARE nPos INT(11) DEFAULT 1;
DECLARE cChar VARCHAR(1);
SET cNewValue := '';
WHILE nPos <= LENGTH( cValue ) DO
SET cChar := SUBSTR( cValue, nPos, 1 );
IF ( cChar >= '0' AND cChar <= '9' ) OR ( cChar >= 'A' and cChar <= 'Z' ) THEN
SET cNewValue := CONCAT( cNewValue, cChar );
END IF;
SET nPos = nPos + 1;
END WHILE;
RETURN cNewValue;
END
Código: Selecionar todos
CREATE FUNCTION ze_CalculaDigito(
cNumero VARCHAR(100),
nModulo INT(11)
)
RETURNS VARCHAR(1)
/* 2024.10.18 CNPJ alpha */
BEGIN
DECLARE nFator INT(11);
DECLARE nSoma INT(11);
DECLARE nPos INT(11);
DECLARE nResto INT(11);
IF LENGTH( cNumero ) < 1 THEN
RETURN '';
END IF;
SET nFator = 2;
SET nSoma = 0;
SET nPos = LENGTH( cNumero );
IF nModulo = 10 THEN
WHILE nPos > 0 DO
SET nSoma = nSoma + ( ASCII( SUBSTR( cNumero, nPos, 1 ) ) - 48 ) * nFator ) ;
SET nFator = nFator + 1;
SET nPos = nPos - 1;
END WHILE;
ELSE
WHILE nPos > 0 DO
SET nSoma = nSoma + ( ASCII( SUBSTR( cNumero, nPos, 1 ) ) - 48 ) * nFator ) ;
IF nFator = 9 THEN
SET nFator = 2;
ELSE
SET nFator = nFator + 1;
END IF;
SET nPos = nPos - 1;
END WHILE;
END IF;
SET nResto = 11 - MOD( nSoma, 11 );
IF nResto > 9 THEN
SET nResto = 0;
END IF;
RETURN CAST( nResto AS CHAR(1) );
END
harbour
Código: Selecionar todos
FUNCTION ValidCnpj( cCnpj )
LOCAL cNumero, lOk, cPicture := "@R 99.999.999/9999-99"
cNumero := PadL( SoNumeroCnpj( cCnpj ), 14, "0" )
cNumero := Left( cNumero, 12 )
cNumero := cNumero + CalculaDigito( cNumero, "11" )
cNumero := cNumero + CalculaDigito( cNumero, "11" )
lOk := ( SoNumero( cNumero ) == SoNumero( cCnpj ) )
IF lOk
cCnpj := Pad( Transform( cNumero, cPicture ), Max( 18, Len( cCnpj ) ) )
ENDIF
RETURN lOk
Código: Selecionar todos
FUNCTION SoNumeroCnpj( cTxt )
LOCAL cSoNumeros := "", cChar
FOR EACH cChar IN cTxt
IF ( cChar >= "0" .AND. cChar <= "9" ) .OR. ( cChar >= "A" .AND. cChar <= "Z" )
cSoNumeros += cChar
ENDIF
NEXT
RETURN cSoNumeros
Código: Selecionar todos
FUNCTION CalculaDigito( cNumero, cModulo )
LOCAL nFator, nPos, nSoma, nResto, nModulo, cCalculo
hb_Default( @cModulo, "11" )
IF Empty( cNumero )
RETURN ""
ENDIF
cCalculo := AllTrim( cNumero )
nModulo := Val( cModulo )
nFator := 2
nSoma := 0
IF nModulo == 10
FOR nPos = Len( cCalculo ) To 1 Step -1
nSoma += Val( Substr( cCalculo, nPos, 1 ) ) * nFator
nFator += 1
NEXT
ELSE
FOR nPos = Len( cCalculo ) To 1 Step -1
nSoma += ( Asc( Substr( cCalculo, nPos, 1 ) ) - 48 ) * nFator
IF nFator == 9
nFator := 2
ELSE
nFator += 1
ENDIF
NEXT
ENDIF
nResto := 11 - Mod( nSoma, 11 )
IF nResto > 9
nResto := 0
ENDIF
cCalculo := Str( nResto, 1 )
RETURN cCalculo
Só falta um CNPJ alfanumérico pra testar...
Como sempre falo:
É errado querer ganhar tempo na criação de fonte.
Tem que fazer fonte simples e claro, pra ganhar tempo na manutenção.
O que poderia ser problema em 2026, não é mais, será tempo livre pra alguma outra coisa.