Mostrando postagens com marcador Funções úteis. Mostrar todas as postagens
Mostrando postagens com marcador Funções úteis. Mostrar todas as postagens

quarta-feira, 1 de novembro de 2023

Transformando String de Inteiros em Lista usando Programação Funcional

             Nesse artigo vou mostrar como transformar uma String de números inteiros separadas por “;” em um Array de Integer usando programação funcional em Java.

         

       A programação funcional ajuda muito a reduzir códigos, embora possa também, dependendo da forma que utilizada, perder um pouco legibilidade dele. Então as vezes usar uma forma não tão reduzida das funções e colocar comentários ajuda bastante. Lembre-se que nem todo mundo que programa tem o mesmo nível de experiência.

 

          O código abaixo monta um Stream (Um Stream é uma sequência de elementos que pode ser processada de forma sequencial ou paralela) a partir do split da String, usando o Map para transformar os dados (ele pode ser usado para converter tipos de dados, para chamar funções como UpperCase, etc.) e depois retornados como uma lista.

 

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

 

public class Exemplo {

    public static void main(String[] args) {

 

        String str = "10;20;30;40;50";

  

        List<Integer> integerList = Arrays.stream(str.split(";"))

                .map(Integer::parseInt)

                .collect(Collectors.toList());

       

        integerList.forEach(System.out::println);

    }

}

quarta-feira, 26 de julho de 2023

Trabalhando com Arquivos (File) e Array de Bytes no Java

     As vezes precisamos transformar um arquivo em array de bytes e visse e versa seja para guardar o arquivo em banco ou tranferir na rede, e aqui seguem duas funções para fazer esse De-Para:


        public byte[] convertFileToByte(File file){
FileInputStream fileInputStream=null;
byte[] bFile = new byte[(int) file.length()];
try {
    //convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
   
}catch(Exception e){
e.printStackTrace();
}
return bFile;
}

public File convertByteToFile(byte[] bYtes){
File file = new File("file");
BufferedOutputStream bos;
try {
bos = new BufferedOutputStream(new FileOutputStream(file));
bos.write(bYtes); 
bos.close(); 
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();

return file;
}

quarta-feira, 12 de julho de 2023

Juntando Strings JSON

     Nesse artigo vou mostrar um método que junta até 3 JSONs em um só, sendo que qualquer um deles pode vir vazio ou nulo. Esse método foi usado para uma integração onde recebia até 3 respostas e precisava tratá-las como uma na aplicação. 


private String montaJson(String json, String json2, String json3) {

if(json != null && !json.isEmpty()){

    json = json.trim().substring(0, json.lastIndexOf("]"))+",";

    if(json2 != null && !json2.isEmpty()){

json += json2.trim().substring(1, json2.lastIndexOf("]"))+",";

if(json3 != null && !json3.isEmpty()){

json += json3.trim().substring(1);

} else {

    json = json.trim().substring(0, json.lastIndexOf(","))+"]";

}

    } else if(json3 != null && !json3.isEmpty()) {

json += json3.trim().substring(1, json3.lastIndexOf("]"));

    } else {

        json = json.trim().substring(0, json.lastIndexOf(","))+"]";

    }

} else {

if(json2 != null && !json2.isEmpty()){

    json = json2.trim().substring(0, json2.lastIndexOf("]"))+",";

    if(json3 != null && !json3.isEmpty()) {

        json += json3.trim().substring(1);

    } else {

              json = json.trim().substring(0, json.lastIndexOf(","))+"]";

    }

} else if(json3 != null && !json3.isEmpty()){

    json = json3.trim();

}

}

return json;

}

quarta-feira, 24 de maio de 2023

Uso de transações e variáveis em SQL Server, Oracle e PostgreSQL

Neste artigo vou mostrar o uso de transação e de declaração de variável nos Bancos de Dados mais utilizados: SQL Server, Oracle e PostgreSQL.

 

As vezes você pode por exemplo usar um SELECT pra retornar um ID e guardar ele em uma variável para depois fazer várias ações com ele, e essas ações precisam ser feitas por completo ou então você precisa desfazer o que foi executado parcialmente. Nos exemplos a seguir, o trecho que executa o DELETE serve como exemplo para aonde as ações seriam colocadas.

 

Segue o exemplo para SQL Server:

 

BEGIN TRANSACTION;

      DECLARE @nomeVariavel tipoVariavel; (alguns tipos como CHAR e VARCHAR precisam do tamanho entre parenteses junto ao tipo : varchar(30))


      SELECT @nomeVariavel = coluna

      FROM tabela WHERE condição;


      DELETE FROM tabela

      WHERE coluna = @nomeVariavel;

 

IF @@ERROR <> 0

      BEGIN

      ROLLBACK TRANSACTION;

      END

ELSE

      BEGIN

            COMMIT TRANSACTION;

      END

 

Segue o exemplo para Oracle:

 

DECLARE nome_da_variavel datatype;

BEGIN

nome_da_variavel := valor;

 

DELETE FROM tabela WHERE coluna = nome_da_variavel;

              

BEGIN

                

EXCEPTION WHEN others THEN

                 ROLLBACK;

                 RAISE;

              

END;

COMMIT;

END;

 

E por fim, segue o exemplo para PostgreSQL:

 

BEGIN;

DECLARE nome_da_variavel datatype;

nome_da_variavel := valor;

 

DELETE FROM tabela WHERE coluna = nome_da_variavel;

 

BEGIN

    EXCEPTION WHEN others THEN

        ROLLBACK;

        RAISE;

END;

COMMIT;

 

Pra esse artigo é isso, espero que ajude.

terça-feira, 10 de janeiro de 2023

Java AES/CBC criptografia e descriptografia

 

Nesse artigo vou mostrar como criptografar e descriptografar um texto usando criptografia bidirecional assimétrica, ou seja, de chave única e privada. Esse tipo de criptografia é útil por exemplo para enviar uma URL de recuperação de senha para um usuário ou mesmo proteger o token de acesso.

 

Vamos usar o algoritmo AES (Advanced Encryption Standard) que possui algumas variações, da qual vamos usar o CBC - Cipher Block Chaining (Encadeamento de blocos cifrados). O modo CBC usa um vetor de inicialização (IV) para aumentar a criptografia. Primeiro, o CBC usa o bloco de texto simples XOR com o IV. Em seguida, ele criptografa o resultado para o bloco de texto cifrado. No próximo bloco, ele usa o resultado da criptografia para XOR com o bloco de texto simples até o último bloco. Uma das principais características do CBC é que ele usa um processo de encadeamento que faz com que a descriptografia de um bloco de texto cifrado dependa de todos os blocos de texto cifrado anteriores.

 

*XOR = Ou exclusivo ou disjunção exclusiva é um mecanismo de codificação usado para combinar diferentes entradas.

 

Vamos aos códigos. Serão 2 classes e um Teste Unitário para garantirmos que tudo está certo.

 

import java.security.spec.KeySpec;

 

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.spec.SecretKeySpec;

 

/**

 * Advanced Encryption Standard ( AES )

 *

 * @author Daniel Oliveira

 *

 * IV = Initialization Vector ou Vetor de inicialização

 *  é uma entrada para uma primitiva criptográfica sendo usada para fornecer

 *  o estado inicial. O IV geralmente precisa ser aleatório ou pseudo -aleatório,

 *  mas às vezes um IV só precisa ser imprevisível ou único.

 * 

 *  o AES tem um tamanho de bloco de 128 bits ou 16 bytes. O AES não altera o

 *  tamanho, e o tamanho do texto cifrado é igual ao tamanho do texto não

 *  criptografado. Além disso, nos modos ECB e CBC, devemos usar um algoritmo

 *  de preenchimento como PKCS 5. Portanto, o tamanho dos dados após a criptografia é: 256

 */

public class SymmetricCripto {     

      private static final String AES = "AES";

      private static final int ITERATION_COUNT = 65536;

      private static final int KEY_LENGTH = 256;

      private static final String ALGORIHM = "AES/CBC/PKCS5Padding";

      private static final String SECRET_KEY_FACTORY_INSTANCE = "PBKDF2WithHmacSHA256";

      private static final String ENCODING = "UTF-8";

// crie seu IV com 16 Bytes.

      private static final String IV = "8P7A6S5S4W3O2R1D";

 

      public static byte[] cripto(String text, SecretKey password )   {

            try {

                  return cripto(password, text.getBytes(ENCODING));

            } catch (Exception exception) {

                  exception.printStackTrace();

                  return new byte[0];

            }

      }

     

      private static byte[] cripto(SecretKey secretKey, byte[] text )   {

            try {

                  Cipher cipher = Cipher.getInstance(ALGORIHM);

                  cipher.init(Cipher.ENCRYPT_MODE, secretKey, generateIv());

                  return cipher.doFinal(text);

            } catch (Exception exception) {

                  exception.printStackTrace();

                  return new byte[0];

            }

      }

     

      public static byte[] descripto(SecretKey secretKey, byte[] text )   {

            try{

                  Cipher cipher = Cipher.getInstance(ALGORIHM);

                  cipher.init(Cipher.DECRYPT_MODE, secretKey, generateIv());

            return cipher.doFinal(text);

            } catch (Exception exception) {

                  exception.printStackTrace();

                  return new byte[0];

            }

      }

     

      public static SecretKey getSecretKey(String password, String salt){

            SecretKey secret = null;

            try {

                  SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_INSTANCE);                 

                  KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), ITERATION_COUNT, KEY_LENGTH);

                  secret = new SecretKeySpec(factory.generateSecret(keySpec)

                      .getEncoded(), AES);

            } catch (Exception e) {

                  e.printStackTrace();

            }

          return secret;

      }

     

      public static IvParameterSpec generateIv() {

        byte[] iv = IV.getBytes();

        return new IvParameterSpec(iv);

    }

}

 

public final class Util {

      private static final String SALT = "12345678";

// crie seu PASSWORD com 16 Bytes.

      private static final String PASSWORD = "P1A2S3S4W5O6R7D8";

      public static String createToken(String username) {

            Timestamp currentTimeStamp = new Timestamp(Calendar.getInstance().getTime().getTime());

            return username + "_" + currentTimeStamp.toString();

      }

 

      public static String encodeToken(String token) {

            SecretKey secretKey = SymmetricCripto.getSecretKey(PASSWORD, SALT);

            byte[] criptografado = SymmetricCripto.cripto(token, secretKey);

            return Base64.getUrlEncoder().encodeToString(criptografado);      

      }

 

      public static String decodeToken(String token) {

            byte[] decodedBytes = Base64.decode(token.getBytes());

            SecretKey secretKey = SymmetricCripto.getSecretKey(PASSWORD, SALT);

            token = new String(SymmetricCripto.descripto(secretKey, decodedBytes), Charset.forName("UTF-8"));

            return token;

      }

}

 

         E agora para testar a criptografia vamos ver a classe de teste:

 

public class UtilTeste {

      @Test

      public void criptografaTokenTest() {

            String token = Util.createToken("Daniel");

            String tokenCriptografado = Util.encodeToken(token);

            String tokenDescriptografado = Util.decodeToken(tokenCriptografado);

            Assert.assertTrue(token.equals(tokenDescriptografado));

      }

     

      @Test

      public void criptografaTokenTest2() {      

            String token = Util.createToken("Daniel");

            String token2 = Util.createToken("Gadiel");

            System.out.println(token);

            System.out.println(token2);

 

            String tokenCriptografado1 = Util.encodeToken(token);

            System.out.println(tokenCriptografado1);

 

            String tokenCriptografado2 = Util.encodeToken(token2);

            System.out.println(tokenCriptografado2);

 

            String tokenDescriptografado1 = Util.decodeToken(tokenCriptografado1);

            System.out.println(tokenDescriptografado1);

 

            String tokenDescriptografado2 = Util.decodeToken(tokenCriptografado2);

            System.out.println(tokenDescriptografado2);

 

             Assert.assertTrue(token.equals(tokenDescriptografado1) && token2.equals(tokenDescriptografado2));

      }

 

      @Test

      public void criptografaTokenTest3() {

            String token = "Daniel_2023-01-10 18:58:09.642";

            String token2 = "Gadiel_2023-01-10 18:58:09.642";

            System.out.println(token);

            System.out.println(token2);

 

            String tokenCriptografado1 = Util.encodeToken(token);

            System.out.println(tokenCriptografado1);

 

            String tokenCriptografado2 = Util.encodeToken(token2);

            System.out.println(tokenCriptografado2);

 

            String tokenDescriptografado1 = Util.decodeToken(tokenCriptografado1);

            System.out.println(tokenDescriptografado1);

 

            String tokenDescriptografado2 = Util.decodeToken(tokenCriptografado2);

            System.out.println(tokenDescriptografado2);

 

            Assert.assertTrue(
tokenCriptografado1.equals("KOlEIFpg8oWmgIPQlwIZ9Ibaz4DU0Fq3Fx7ZWHwmLKw="&&    tokenCriptografado2.equals("7NzCr0fzeSNy9X2Ib+mjuFPY3EmTM03gpThBW5q6A3o="));

      }

}

 

Importante: Para se ter sempre o mesmo resultado de criptografia e descriptografia para valores iguais após a reinicialização do servidor ou em servidores diferentes (para quem usa cluster ou coisa do tipo) o PassWord que gera a SecretKey e o IV devem ser criados com o mesmo valor sempre. Note que eles são constantes no código.

 

Dica: O token pode (e deve) ser melhorado com o acréscimo de um número randômico e mais dados de acordo com a necessidade. O PassWord e o IV também devem ser alterados de tempos em tempos.

 

Solução adaptada à necessidade que tive a partir das seguintes fontes:

https://www.devmedia.com.br/introducao-a-seguranca-da-informacao-em-java/28247

https://www.baeldung.com/java-aes-encryption-decryption

https://www.techtarget.com/searchsecurity/definition/cipher-block-chaining

https://stackoverflow.com/questions/54874072/aes-encryption-in-node-resulting-is-different-output-compared-to-java