4

I am trying to store a mapping of letters to a Binary number. Here is my Mapping

("h",001)
("i", 010)
("k",011)
("l",100)
("r", 101)
("s",110)
("t",111)

For this purpose, I have created a hash map and stored the key value pairs. I now want to display the corresponding binary value, for a given sentence. Here is my code for the same.

package crups;

import java.util.*; 


public class onetimepad {

public static void main(String args[])
{
    HashMap <String , Integer>hm  = new HashMap <String , Integer> (); 
    hm.put("e", 000);
    hm.put("h",001);
    hm.put("i", 010);
    hm.put("k",011);
    hm.put("l",100);
    hm.put("r", 101);
    hm.put("s",110);
    hm.put("t",111);



    String[] key = { "t" ,"r" , "s" , "r","t","l","e", "r","s","e"};
    //key = t r s r t l e r s e
    String[] input = {"h","e","i" ,"l","h","i","t","l","e","r"};
    int[] cipher = new int[10]; 
    System.out.println("Binary form of text is ....");

    for( String s : input )
    {
        System.out.print(hm.get(s)+" ");
    }

}   

}

When I run the code however, the mapping for the letter "i" is shown wrong : 8 : instead of 010. Can some one please tell me why this is happening? Also how can I display the zeroes infront of my numbers, as these are binary numbers. Thanks.

Output :

Binary form of text is ....
1 0 8 100 1 8 111 100 0 101 
malioboro
  • 3,097
  • 4
  • 35
  • 55
  • 4
    Store them as strings ("001") instead of numbers. – shmosel Jan 31 '17 at 04:31
  • That's some interesting input text you've got there too. – Luke Briggs Jan 31 '17 at 04:33
  • My next step in the problem is to be able to perform a "xor" operation on the binary numbers . if i use them as strings , i will have to convert them to int , and then perform the xor ? Can there be an alternative , so that i can directly store them as binary in my map .@shmosel – vishrut sharma Jan 31 '17 at 04:34
  • 1
    @LukeBriggs: haha , its apparently an easy text to form different sentences , by permutations . – vishrut sharma Jan 31 '17 at 04:35
  • 1
    The numbers that you're looking at in your source are decimal - `101` is "One hundred and one", for example. You'd pick the decimal numbers that represent the binary you want. (e.g. decimal `4` is `100` in binary), then use something like [converting an int to a binary string](http://stackoverflow.com/questions/29404398/converting-an-int-to-a-binary-with-a-fixed-number-of-bits) to conveniently display the bits :) – Luke Briggs Jan 31 '17 at 04:38
  • @LukeBriggs thank you . that seems doable :) But i am still clueless as to why , the representation on "i" is an 8 . O.o – vishrut sharma Jan 31 '17 at 04:50
  • @vishrutsharma It's because numbers that start with a 0 are represented in base 8 (octal), and 010 is 8 in octal. – Jacob G. Jan 31 '17 at 04:51
  • See also [why isn't 08 valid in Java](http://stackoverflow.com/questions/7218760/why-is-08-not-a-valid-integer-literal-in-java) - the numbers that start with a single 0 are actually intepreted as being octal. Start it with 0x and you get hex. _0b and you get bits (this is so rarely used I totally forgot about it)_. 0xff (dec: 255), 010 (dec: 8), 101 (dec: 101), 0b101 (dec: 5). – Luke Briggs Jan 31 '17 at 04:53
  • 1
    @shmosel *Store them as strings ("001") instead of numbers.* Now who's cheating? – Elliott Frisch Jan 31 '17 at 05:11
  • @ElliottFrisch OP is obviously trying to hardcode the binary values. I'm just helping him out. – shmosel Jan 31 '17 at 05:13

3 Answers3

2

You just can't store them with leading zero. Leading zero to an integer indicates that it's an octal number.

Since your next step is XOR, I recommend this approach.

  1. You can store these integers using simple base 10 numbers. We will convert them when needed as binary. (you can also store them simply as binary with leading 0b. See this answer for more details.
  2. Use Integer.toString(hm.get(s), 2); to display binary number. The original number is still an Integer so you can use it for XOR operation.
  3. For displaying binary with leading zero, I've played with some string methods like this:

    String temp = "000", binary;
    for( String s : input ) {
        binary = Integer.toString(hm.get(s), 2);
        System.out.print(temp.substring(0, 3-binary.length()) + binary +" ");
    }
    

Here's what the final code looks like:

Output

Binary form of text is ....
001 000 010 100 001 010 111 100 000 101 

Code

import java.util.*;

public class onetimepad {
    public static void main(String args[]) {
        HashMap <String , Integer>hm  = new HashMap <String , Integer> (); 
        hm.put("e", 0); //or use hm.put("e", 0b000);
        hm.put("h", 1); //or use hm.put("e", 0b001);
        hm.put("i", 2);
        hm.put("k", 3);
        hm.put("l", 4);
        hm.put("r", 5);
        hm.put("s", 6);
        hm.put("t", 7);

        String[] key = { "t" ,"r" , "s" , "r","t","l","e", "r","s","e"};
        //key = t r s r t l e r s e
        String[] input = {"h","e","i" ,"l","h","i","t","l","e","r"};
        int[] cipher = new int[10]; 
        System.out.println("Binary form of text is ....");

        String temp = "000", binary;
        for( String s : input ) {
            binary = Integer.toString(hm.get(s), 2);
            System.out.print(temp.substring(0, 3-binary.length()) + binary +" ");
        }
    }   
}
Community
  • 1
  • 1
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
  • **Health warning:** XOR results will feel completely random (the OP stated in comments above that the next step is to use XOR on them). – Luke Briggs Jan 31 '17 at 04:59
  • 1
    @LukeBriggs my bad. I didn't saw that comment. However, thanks for notifying, I've updated my answer accordingly. – Raman Sahasi Jan 31 '17 at 05:18
2

First, your Map declaration and initialization is a bit off. To use binary constants you prefix it with 0b - and please program to the Map interface (not the HashMap implementation). And, since Java 7, you can use the diamond operator <> to shorten things up.

Map<String, Integer> hm = new HashMap<>();
hm.put("e", 0b000);
hm.put("h", 0b001);
hm.put("i", 0b010);
hm.put("k", 0b011);
hm.put("l", 0b100);
hm.put("r", 0b101);
hm.put("s", 0b110);
hm.put("t", 0b111);

Then, for printing, you have Integer(s) but you want their binary representation. So you can do something like,

for (String s : input) {
    System.out.print(Integer.toBinaryString(hm.get(s)) + " ");
}

Which I ran to get (as I believe you expected)

Binary form of text is ....
1 0 10 100 1 10 111 100 0 101 

If you really want the leading zeros (a three bit binary format) you could do,

for (String s : input) {
    StringBuilder sb = new StringBuilder(Integer.toBinaryString(hm.get(s)));
    while (sb.length() < 3) {
        sb.insert(0, '0');
    }
    System.out.print(sb.append(" "));
}

Which outputs

Binary form of text is ....
001 000 010 100 001 010 111 100 000 101 
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thank you very much . This was precise . To make sure i got you correct , i can store binary numbers into int by the simple format of " 0b000"...."0b100" and so onn . – vishrut sharma Jan 31 '17 at 22:30
  • @vishrutsharma That is how you use a binary literal. All numbers are binary in a digital computer. – Elliott Frisch Jan 31 '17 at 22:42
  • In this case , i need not use the whole "Integer.toBinaryString" and so can directly display the contents of my hash map (without converting to String ) . Subsequently perform XOR on the contents , without having to perform any conversions. – vishrut sharma Jan 31 '17 at 23:00
0

Thanks for your inputs guys . I have finished one part of my problem , that required me to encrypt my input text : "Heilhitler " and present it in the binary format . This was the code i was able to build with your suggestions .

public static void main(String args[])
    {
        HashMap <String , Integer>hm  = new HashMap <String , Integer> (); 
        hm.put("e", 0);
        hm.put("h",1);
        hm.put("i", 2);
        hm.put("k",3);
        hm.put("l",4);
        hm.put("r",5);
        hm.put("s",6);
        hm.put("t",7);
String[] key = { "t" ,"r" , "s" , "r","t","l","e", "r","s","e"};
    //key = t r s r t l e r s e
    String[] input = {"h","e","i" ,"l","h","i","t","l","e","r"};

    int[] inter1 = new int[10];     
    System.out.println("Binary form of text is ....");
    int i = 0 ; 
    for( String s : input )
    { 

        String binarystr = Integer.toBinaryString(hm.get(s)) ; 
        System.out.print( binarystr+" ");
        inter1[i]=Integer.parseInt(binarystr) ; 
        i++ ; 
    }

    int[] inter2 = new int[10]; 
    int m= 0 ; 
    for( String s : key )
    { 
        String binarystr = Integer.toBinaryString(hm.get(s)) ; 
        System.out.print( binarystr+" ");
        inter2[m]=Integer.parseInt(binarystr) ; 

        m++ ; 
    }


    int[] cipher = new int[10];
    for(int j = 0 ; j < 10 ; j++)
    {
        cipher[j] = inter1[j] ^ inter2 [j];   //performing xor between input and key 
    }
    System.out.println("Cipher is .....");
    for( int j= 0 ; j < 10;  j++ )
    {
        System.out.print(" " + cipher[j]);
    }

   //-------------------Decryption //----------------------------
    //Performing XOR between the cipher and key again 
    int[] decry = new int[10] ; 

    for(int j = 0 ; j < 10 ; j ++ )
    {
        decry[j] = cipher[j] ^ inter2[j]; 
    }
    System.out.println(" ");
    System.out.println("Decrypted result in Binary format");
    for( int j= 0 ; j < 10;  j++ )
    {
        System.out.print(" " + decry[j]);
    }

    }
  }

Output:

Binary form of text is ....
1 0 10 100 1 10 111 100 0 101  
Cipher is .....
110 101 100 1 110 110 111 1 110 101 
Decrypted result in Binary format
1 0 10 100 1 10 111 100 0 101