Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Java / Cifrado francmasón PigPen

Cifrado francmasón PigPen

Autor jc mouse domingo, agosto 16, 2015

El cifrado francmasón es un cifrado por sustitución simple que cambia las letras por símbolos. Sin embargo, el uso de símbolos no impide el criptoanálisis, y el criptoanálisis es idéntico al de otros métodos de cifrado por substitución simple.

Llamado también “cifra Pigpen” este método de cifrado fue utilizado por los masones en el siglo XVIII para preservar la privacidad de sus archivos. Se basa en la sustitución de cada letra por un símbolo de acuerdo al siguiente modelo:

cifrado simple

Para codificar una letra en particular, se debe encontrar su posición en una de las cuatro cuadrículas y luego se dibuja esa porción de la cuadrícula para representar esa letra. Por tanto el mensaje “HOLA MUNDO” cifrado bajo este sistema tendría la siguiente forma:

hola pigpen

Otro ejemplo un poco mas largo, es  el siguiente, el juramento de la Guardia Nocturna de la serie Juegos de Tronos:

Escuchad mis palabras, sed testigos de mi juramento.
La noche se avecina, ahora empieza mi guardia.
No terminará hasta el día de mi muerte.
No tomaré esposa, no poseeré tierras, no engendraré hijos.
No llevaré corona, no alcanzaré la gloria.
Viviré y moriré en mi puesto.
Soy la espada en la oscuridad.
Soy el vigilante del Muro.
Soy el fuego que arde contra el frío,
la luz que trae el amanecer,
el cuerno que despierta a los durmientes,
el escudo que defiende los reinos de los hombres.
Entrego mi vida y mi honor a la Guardia de la Noche,
durante esta noche y todas las que estén por venir.

Este texto cifrado, tiene la siguiente forma:

juramento guardia nocturna

Proyecto Java

https://youtu.be/zeX-Oh_-x5c

Las clases principales son:

  • Clase Letter: Se encarga de dibujar las letras A..Z  cifradas y en su estado normal
  • Clase Sheet: Se extiende de un JPanel y nos sirve de lienzo para pintar el mensaje cifrado

Clase Letter

package com.bolivia.pigpen;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

/**
 * @web http://www.jc-mouse.net/
 * @author Mouse
 */
public class Letter {

    private Point point                 =       new Point(0,0);
    private final int SIZE_BOX          =       24;
    //tamaño y posicion de letra 
    private int x                       =       0;
    private int y                       =       0;
    private final int WIDTH             =       16;
    private final int HEIGHT            =       16;   
    //
    private final Font FONT_CHAR        =       new Font("Tahoma", Font.BOLD, 16 );
    private Dimension dimensionText;
    private String letter               =       "A";    
    private Color COLOR_CHAR            =       new Color(0,0,0);
    private final Stroke STROKE_CHAR    =       new BasicStroke(2f);
    private final Stroke STROKE_0       =       new BasicStroke(0);

    /**
 * Constructor de clase
 * @param String letter letra de A..Z o cualquier otro caracter, si no es A..z no se cifra
 */
    public Letter(String letter){
        this.letter = letter;
        x = point.x+4;
        y = point.y+4;     
    }

    /**
 * Constructor de clase
 * @param String letter letra de A..Z o cualquier otro caracter, si no es A..z no se cifra
 * @param Point coordenada X,Y de letra/caracter
 */
    public Letter(String letter, Point point){
        this.letter = letter.toUpperCase();
        this.point = point;
        x = point.x+4;
        y = point.y+4;        
    }

    /**
 * Metodo para pintar una letra/caracter 
 */
    public void drawLetter(Graphics2D g2){                  
        g2.setStroke(STROKE_CHAR);        
        g2.setColor( COLOR_CHAR );
        if(letter.equals("A") || letter.equals("J") ){
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT); // _
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);  // |
            if(letter.equals("J")){
                g2.setStroke(STROKE_0);   
                g2.fillRect(x+WIDTH-8, y+HEIGHT-8,6, 6);    
            }            
        } else if(letter.equals("B") || letter.equals("K") ){            
            g2.drawLine(x, y, x, y+HEIGHT);              // |
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT); // _ 
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);  // | 
            if(letter.equals("K")){
                g2.setStroke(STROKE_0);
                g2.fillRect(x+WIDTH/2-3, y+HEIGHT-8,6, 6);    
            }            
        } else if(letter.equals("C") || letter.equals("L")){            
            g2.drawLine(x, y, x, y+HEIGHT);              // |
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT); // _ 
            if(letter.equals("L")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+2, y+HEIGHT-8,6, 6);    
            }    
        } else if(letter.equals("D") || letter.equals("M")){            
            g2.drawLine(x, y, x+WIDTH, y);               // - 
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT);        
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);            
            if(letter.equals("M")){
                g2.setStroke(STROKE_0);    
                g2.fillRect(x+WIDTH-8, y+HEIGHT/2-3,6, 6);    
            }    
        }else if(letter.equals("E") || letter.equals("N")){            
            g2.drawLine(x, y, x+WIDTH, y);               // -
            g2.drawLine(x, y, x, y+HEIGHT);              // |
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT); // _ 
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);  // | 
             if(letter.equals("N")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+WIDTH/2-3, y+HEIGHT-8,6, 6);    
            }  
        }else if(letter.equals("F") || letter.equals("O")){            
            g2.drawLine(x, y, x+WIDTH, y);               // -
            g2.drawLine(x, y, x, y+HEIGHT);              // |
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT); // _ 
            if(letter.equals("O")){
                g2.setStroke(STROKE_0);  
                g2.fillRect(x+2, y+HEIGHT/2-3,6, 6);    
            }   
        }else if(letter.equals("G") || letter.equals("P")){            
            g2.drawLine(x, y, x+WIDTH, y);               // - 
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);            
            if(letter.equals("P")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+WIDTH-8, y+2,6, 6);    
            }  
        }else if(letter.equals("H") || letter.equals("Q")){            
            g2.drawLine(x, y, x+WIDTH, y);               // -
            g2.drawLine(x, y, x, y+HEIGHT);              // | 
            g2.drawLine(x+WIDTH, y, x+WIDTH, y+HEIGHT);  // | 
            if(letter.equals("Q")){
                g2.setStroke(STROKE_0);
                g2.fillRect(x+WIDTH/2-3, y+2,6, 6);    
            }  
        }else if(letter.equals("I") || letter.equals("R")){            
            g2.drawLine(x, y, x+WIDTH, y);               // -
            g2.drawLine(x, y, x, y+HEIGHT);              // | 
            if(letter.equals("R")){
                g2.setStroke(STROKE_0);    
                g2.fillRect(x+2, y+2,6, 6);    
            }  
        }else if(letter.equals("T") || letter.equals("X")){    //> 
            g2.drawLine(x, y, x+WIDTH, y+HEIGHT/2);               
            g2.drawLine(x, y+HEIGHT, x+WIDTH, y+HEIGHT/2);               
            if(letter.equals("X")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x, y+HEIGHT/2-3,6, 6);    
            }
        }else if(letter.equals("U") || letter.equals("Y")){ //<
            g2.drawLine(x, y+HEIGHT/2, x+WIDTH, y);               
            g2.drawLine(x, y+HEIGHT/2, x+WIDTH, y+HEIGHT);               
            if(letter.equals("Y")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+WIDTH-6, y+HEIGHT/2-3,6, 6);    
            }
        }else if(letter.equals("S") || letter.equals("W")){ // \/
            g2.drawLine(x, y, x+WIDTH/2, y+HEIGHT);               
            g2.drawLine(x+WIDTH, y, x+WIDTH/2, y+HEIGHT);               
            if(letter.equals("W")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+WIDTH/2-3, y,6, 6);    
            }
        }else if(letter.equals("V") || letter.equals("Z")){ // /\
            g2.drawLine(x+WIDTH/2, y, x, y+HEIGHT);               
            g2.drawLine(x+WIDTH/2, y, x+WIDTH, y+HEIGHT);               
            if(letter.equals("Z")){
                g2.setStroke(STROKE_0); 
                g2.fillRect(x+WIDTH/2-3, y+HEIGHT-8,6, 6);    
            }
        }else{// si no corresponde a ninguna letra de A..Z pinta el original 
            //que puede ser una letra con acento, un numero u otro caracter especial 
            if(letter.length()>0){
                dimensionText = calculateFontDimension(letter);
                g2.setFont(FONT_CHAR); 
                g2.drawString( letter, point.x+SIZE_BOX/2-dimensionText.width/2, point.y + SIZE_BOX/2 + dimensionText.height/2);    
            }            
        }

    }

    /**
 * Pinta una letra de A..Z en java2d
 */
    public void paintLetter(Graphics2D g2){          
        g2.setColor( COLOR_CHAR );
        dimensionText = calculateFontDimension(letter);
        g2.setFont(FONT_CHAR); 
        g2.drawString( letter, point.x+SIZE_BOX/2-dimensionText.width/2, point.y + SIZE_BOX/2 + dimensionText.height/2);    
    }

    /**
 * Metodo que retorna una imagen 
 * @param band si
 * TRUE: retorna letra cifrada
 * FALSE: retorna letra sin cifrar
 * @return BufferedImage
 */
    public BufferedImage getImage(boolean band){
        BufferedImage bufferedImage = new BufferedImage(SIZE_BOX, SIZE_BOX, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bufferedImage.createGraphics();
        g2d.setColor( new Color(255,255,255));   
        g2d.fill(new Rectangle2D.Double(0,0,SIZE_BOX,SIZE_BOX)); 
        if(band)
            drawLetter(g2d);
        else
            paintLetter(g2d);
        g2d.dispose();
        return bufferedImage;
    }

    /**
 * Obtiene las dimensiones de un texto
 * @param String texto
 * @param int f tipo de fuente PLAIN | BOLD | ITALIC
 * @param int size tamaño de fuente
 * @return Dimension
 */
    public Dimension calculateFontDimension(String text){       
            BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = image.createGraphics();            
            g2.setStroke(STROKE_0);            
            TextLayout layout = new TextLayout(text, FONT_CHAR, g2.getFontRenderContext());
            layout.draw(g2, 0, 0);
            Rectangle2D bounds = layout.getBounds();
            bounds.setRect(bounds.getX(),
                  bounds.getY(),
                  bounds.getWidth(),
                  bounds.getHeight());
            int w = (int) bounds.getWidth();
            int h = (int) bounds.getHeight();            
            g2.draw(bounds);
            g2.dispose();
            return new Dimension(w,h);
    }

}//Letter:end

Clase Sheet

package com.bolivia.pigpen;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * @web http://ww.jc-mouse.net/
 * @author Mouse
 */
public class Sheet extends JPanel {

    private final String[] APLHA_ARRAY      = {"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"};
    private List<Letter> letterList         =       new ArrayList<Letter>();         
    private final int MAX_NUM_COLUMN        =       32;    
    private final int SIZE_BOX              =       24;
    private final Color BG_COLOR            =       new Color(255,255,255);
    private Dimension dimension;
    private BufferedImage bufferedImage     =       null;
    private int heightSheet=0;
    private int widthSheet=0;

    /**Constructor de clase */
    public Sheet(){
        super();
        dimension = new Dimension(100,100);
        setBackground(BG_COLOR);
        setSize(dimension);
        setVisible(true);        
    }

    @Override
    public void paintComponent(Graphics g){
        Graphics2D g2 =(Graphics2D) g;        
        bufferedImage = new BufferedImage( widthSheet, heightSheet, BufferedImage.TYPE_INT_RGB );
        Graphics2D graphics2D = bufferedImage.createGraphics();        
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.setColor( BG_COLOR );
        graphics2D.fill(new Rectangle2D.Double(0,0,widthSheet,heightSheet)); 
        //pinta letras/caracter
        for(Letter l:letterList)
        {            
            l.drawLetter(graphics2D);            
        }
        g2.drawImage(bufferedImage, 0, 0, this);

    }

    /**
 * Metodo para escribir en disco
 * @param File file
 */
    public void saveBufferedImage(File file){
        try {           
            if( bufferedImage!=null)
                ImageIO.write(bufferedImage, "png", file);            
 } catch (IOException e) {            
            System.err.println("IOException:" + e.getMessage());
 }
    }

    /**
 * Cifra una cadena de texto y añade letra cifrada en un arrayList
 * @param String texto a cifrar
 */
    public void cifrar(String text){
        //convierte el texto en un array 
        String[] tmpArray = text.split("");               
        String[] textArray = new String[tmpArray.length-1];
        System.arraycopy(tmpArray, 1, textArray, 0, tmpArray.length-1);
        //elimina contenido
        letterList.clear();        
        int row=0;
        int col=0;
        //añade cada letra/caracter en un lista de objetos LETTER junto a su 
        //respectiva posicion en la matriz col x row
        for(String letter: textArray){            
            letterList.add( new Letter(letter, new Point(SIZE_BOX*col,SIZE_BOX*row)) );
            col++;
            if(col == MAX_NUM_COLUMN){
                col=0;
                row++;
            }            
        }        
        //redimensiona JPanel
        dimension = new Dimension(MAX_NUM_COLUMN*SIZE_BOX,SIZE_BOX*row);
        setPreferredSize(dimension);
        setSize(dimension);        
        heightSheet = SIZE_BOX*(row+1);     
        widthSheet = MAX_NUM_COLUMN*SIZE_BOX;
        repaint();        
    }

    /**
 * Metodo para descifrar el contenido de una imagen cifrado por PigPen
 */
    public void descifrar(File file){
        //genera un abecedario de imagenes cifradas
        BufferedImage[] alpha = new BufferedImage[APLHA_ARRAY.length];
        for(int i=0; i<APLHA_ARRAY.length;i++){
            Letter tmp = new Letter(APLHA_ARRAY[i]);
            alpha[i] = tmp.getImage(true);
        }
        //genera un abecedario de imagenes no cifradas
        BufferedImage[] abc = new BufferedImage[APLHA_ARRAY.length];
        for(int i=0; i<APLHA_ARRAY.length;i++){
            Letter tmp = new Letter(APLHA_ARRAY[i]);
            abc[i] = tmp.getImage(false);
        }        
        //lee imagen de archivo
        try {        
            BufferedImage bImage = ImageIO.read(file);             
            //validacion
            if(bImage.getWidth()<SIZE_BOX*MAX_NUM_COLUMN || bImage.getHeight()<SIZE_BOX ){
                JOptionPane.showMessageDialog(null, "Error: La imagen es incorrecta");
                return;
            }
            //crea un array de imagenes extrayendo imagenes 24x24 de imagen principal
            int rows = bImage.getHeight()/SIZE_BOX;
            int cols = MAX_NUM_COLUMN;
            BufferedImage[] imageArray = new BufferedImage[rows * cols];                        
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    imageArray[(i * cols) + j] = bImage.getSubimage(j * SIZE_BOX, i * SIZE_BOX, SIZE_BOX,SIZE_BOX);
                }
            }
            //Array de imagenes destino, aqui se colocal las letras descifradas asi como otros caracteres
            BufferedImage[] imageArrayTarget = new BufferedImage[rows * cols];

            //compara el array de imagenes con array de imagenes A..Z cifradas y va colocando en array de imagenes destino
            for (int k = 0; k < imageArray.length; k++){
                int val=-1;
                for(int p=0; p<alpha.length;p++){//abcdario 
                    double res = compare(imageArray[k],alpha[p]);                        
                    if( res < 1){                    
                        val = p;                    
                        break;
                    }         
                }
                if(val!=-1){
                    imageArrayTarget[k] = abc[val];
                }else{
                   imageArrayTarget[k] = imageArray[k]; 
                }
            }            

            //Crea una imagen en memoria 
            bufferedImage = new BufferedImage(SIZE_BOX*cols, SIZE_BOX*rows, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = bufferedImage.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.setColor( BG_COLOR );
            graphics2D.fill(new Rectangle2D.Double(0,0,SIZE_BOX*cols,SIZE_BOX*rows)); 
            int col=0;
            int row=0;
            for(BufferedImage o:imageArrayTarget){
                graphics2D.drawImage(o, null, SIZE_BOX*col, row);    
                col++;
                if(col==MAX_NUM_COLUMN)
                {
                    col=0;
                    row +=SIZE_BOX;
                }
            }        
            //guarda imagen en disco
            try {    
                String absolutePath = file.getAbsolutePath();        
                String newPath = absolutePath .substring(0, absolutePath .length()-4) + "_" + System.currentTimeMillis() + ".png";                
                ImageIO.write(bufferedImage, "png", new File(newPath));            
                JOptionPane.showMessageDialog(null, "Save: " + newPath );                
                graphics2D.dispose();
            } catch (IOException e) {            
                System.err.println("IOException:" + e.getMessage());
            }             
        } catch (IOException ex) {
            System.err.println("IOException" + ex.getMessage());
        }

    }

    /**
 * Metodo para comparar imagenes
 * @param BufferedImage imagen 1
 * @param BufferedImage imagen 2
 * @return double mientras más alto es el valor de retorno las imagenes son menos iguales
 * 0 : imagene son iguales
 * 100 : las imagenes no son iguales
 * Fuente codigo: http://rosettacode.org/wiki/Percentage_difference_between_images
 */
    private double compare(BufferedImage img1, BufferedImage img2){
        int width1 = img1.getWidth(null);        
        int height1 = img1.getHeight(null);        
            long diff = 0;
            for (int y = 0; y < height1; y++) {
            for (int x = 0; x < width1; x++) {
              int rgb1 = img1.getRGB(x, y);
              int rgb2 = img2.getRGB(x, y);              
              diff += Math.abs(((rgb1 >> 16) & 0xff) - ((rgb2 >> 16) & 0xff));              
              diff += Math.abs(((rgb1 >>  8) & 0xff) - ((rgb2 >>  8) & 0xff));              
              diff += Math.abs(((rgb1      ) & 0xff) - ((rgb2      ) & 0xff));
            }
          }
          double n = width1 * height1 * 3;
          double p = diff / n / 255.0;          
          return p * 100.0;
    }

}//Sheet:end

Descargar proyecto Cifrado PigPen

Enjoy!!!

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Detección de rostros con android

Detección de rostros con android

La API de Android ha ido evolucionado rápidamente y cada vez contiene más funcionalidades que hacen que desarrollar sist...

Consultas con parámetros en Access y Java

Consultas con parámetros en Access y Java

Tenemos un archivo de base de datos Access *.MDB y queremos realizar una consulta con parámetros de búsqueda utilizando...

Bandera en Alto

Bandera en Alto

EL 6 de agosto de cada año se recuerda una de las fechas más importantes de la historia boliviana, porque el 6 de Agosto...

Tabla para inventarios de Entradas y Salidas

Tabla para inventarios de Entradas y Salidas

A veces navegando en la internet buscando novedades , investigando o simplemente perdiendo el tiempo 🙂 se encuentran cos...

Control de versiones con GIT y Netbeans

Control de versiones con GIT y Netbeans

Control de versiones: Se llama control de versiones a la gestión de los diversos cambios que se realizan sobre los eleme...

Impuestos Bolivia :: Código de Control en C#

Impuestos Bolivia :: Código de Control en C#

Hola 🙂 en esta post se deja a disposición de la comunidad de programadores  que quiera aprender un poquito sobre Factura...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

Comparte lo que sabes

Categorias

Últimas entradas

Java ha ido evolucionando a pasos agigantados en los últimos años gracias al pedido de su comunidad global de programado...

pixilart no es solo una herramienta online sino una comunidad de diseñadores a quienes les encanta el arte hecha con...

Repl.it es un proyecto de tres jóvenes emprendedores (Amjad, Haya, Maso), es un compilador en linea el cual te permite p...

Song Maker es el nuevo experimento de Google Chrome Music Lab que permite al usuario crear música desde el navegador a t...

Android Bolivia

MAUS