I'm making Encryption now, and on the step 7 which i need to make the HEX String Array(which I have transferred from ASCII into a String Array) into Binary String.
public static void main(String[] args) {
System.out.println("HEX to Binary: ");
String[] stringHextoBinary = new String[HS.length]; //HS is the String Array for Hex numbers that i save from last step
StringBuilder builder = new StringBuilder();
int l = 0;
for(String s : HS) {
builder.append(s);
if (s.length()<=1){
stringHextoBinary[l] = HexToBinary(s.charAt(0));
l++;
System.out.print(HexToBinary(s.charAt(0)) + ",");
}else{
stringHextoBinary[l] = HexToBinary(s.charAt(0))+HexToBinary(s.charAt(1));
l++;
System.out.print(HexToBinary(s.charAt(0))+HexToBinary(s.charAt(1))+",");
}
public static String HexToBinary(char Hex) {
int i = Integer.parseInt(Character.toString(Hex), 16);
String Bin = Integer.toBinaryString(i);
return Bin;
}
}
the if statement can be work with HEX when it has one digit or two digits.
But my problem is here that it prints out
HEX to Binary:
11100,111,111,10111,11101,
its losing 0 in it. :(
so that when i encrypt word "apple" , and decrypt it with same code will come back with word "pppxl" :(
Hope I can get answer ASAP and thanks a lot!
Use this method of the Apache commons StringUtils class
public String leftPad(String str, int size, char padding);
after you've converted your number to 0s and 1s. It might look like
String paddedBin = StringUtils.leftPad(bin, 8, '0');
for example. Not sure how many digits you actually want to pad it to.
Instead of your method taking in chars, you can simply have it take in a string and convert it to binary using:
public static void main(String[] args) {
System.out.println("HEX to Binary: ");
String[] stringHextoBinary = new String[HS.length]; //HS is the String Array for Hex numbers that i save from last step
// creates the string builder, count, and declaration
StringBuilder builder = new StringBuilder();
int l = 0;
string binaryDigits;
// iterates through string array and appends to string that's being built
// (for whatever reason)
for(String s : HS) {
builder.append(s);
binaryDigits = HexToBinary(s);
stringHextoBinary[l++] = binaryDigits;
System.out.print(binaryDigits);
}
// transforms hex string to binary string without losing 0's
public static String HexToBinary(String Hex) {
string toReturn = new BigInteger(Hex, 16).toString(2);
return String.format("%" + (Hex.length*4) + "s", toReturn).replace(' ', '0')
}
You don't need to combine code, as this is all the code that you need to convert a string to a binary string separated by spaces. It will iterate through and change every string to a binary string.
Try this method implementation:
public static String hexCharToBinary(char c) {
final int v;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'A' && c <= 'F') {
v = 10 + c - 'A';
} else if (c >= 'a' && c <= 'f') {
v = 10 + c - 'a';
} else {
throw new IllegalArgumentException();
}
return String.format("%4s", Integer.toBinaryString(v & 0xFF)).replace(' ', '0');
}
Try this out:
stringHextoBinary[l] = new BigInteger(s,16).toString(2);
What this is doing is creating a new Integer with radix of 16 for you hex numbers and then converting that to a string of base 2 (binary). Haven't tested this out since I am not near a computer with a jvm installed but this is just an idea since you seem to need ideas in a hurry.
This should work too:
stringHextoBinary[l] = Integer.toBinaryString(Integer.parseInt(s, 16));
Related
So I am trying to populate a 2D array from two strings, as seen below.
However, when I go to compile my code, I get a
"java: incompatible types: char[] cannot be converted to char"
error. What am I doing wrong?
public static void main(String[] args) {
String alphabet = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
String iAlphabet = ("ZYXWVUTSRQPONMLKJIHGFEDCBA");
char alphabetArray [][] = {{alphabet.toCharArray()},{iAlphabet.toCharArray()}};
System.out.print(alphabetArray[4][4]);
}
}
(New to Java, and am just bashing my head against a wall on this one)
I guess you want to be able to translate the character from one string to the other one at the same position:
public static void main(String[] args) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
System.out.print("3rd character: " + alphabetArray[0][2] + " -> " + alphabetArray[1][2]);
}
This prints:
3rd character: C -> X
An example of ussage as translate would be:
public static void main(String[] args) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
String test = "HELLO WORLD";
StringBuffer translated = new StringBuffer();
for (int i = 0; i < test.length(); i++) {
int index = alphabet.indexOf(test.charAt(i));
if (index > 0) {
translated.append(alphabetArray[1][index]);
} else {
translated.append(test.charAt(i));
}
}
System.out.println("original sentence: " + test);
System.out.println("translated sentence: " + translated.toString());
}
which prints:
original sentence: HELLO WORLD
translated sentence: SVOOL DLIOW
Declare the arrays as shown below. And remember it's not a 26 x 26 array. It is a 2 x 26 array.
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
Print V from the second.
System.out.print(alphabetArray[1][4]);
Print E from the first.
System.out.print(alphabetArray[0][4]);
You are putting an array of char where you need to place the only char. So remove the curly braces and simply put an array of char
Your Code should be like this
public static void main(String[] args) {
String alphabet = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
String iAlphabet = ("ZYXWVUTSRQPONMLKJIHGFEDCBA");
char[] charArray = alphabet.toCharArray();
char[] charArray2 = iAlphabet.toCharArray();
char alphabetArray[][] = { charArray, charArray2 };
System.out.println(alphabetArray[0][23]);
}
you could also take advantage of the fact that the letters 'A'-'Z' are in order
for example: if you want to translate a number to a letter in the alphabet you can just say
char a = 'A';
a+=num;
or if you want it to go backwards
char a = 'Z';
a-=num;
num being the equivelent index you would've given.
this is assuming that you want to make the array read-only of course, and some sort of validation before performing these operations would be recommended. (Verifying the number is positive and less than 26)
if this works in your case, then that's great.
If you want to do a ceaser cipher: IE translate any character by any offset, you can do the following:
private static char offsetChar(char chr, int offset){
chr = Character.toUpperCase(chr);
//value from 0-25 representing letter
int val = chr - 'A';
//make sure that the offset doesn't make it overflow past 26
val = (val + offset) % 26;
// convert back to letter from number 0-25
return (char)('A' + val);
}
also note that this will auto-capitalize the letter, if you don't want that to happen you can test if it is uppercase and return it in the correct state at the end using
Character.isUpperCase and Character.toUpperCase and Character.toLowerCase
I have a long String with 48bit in Java. This string will be divided into 8 strings with a length of 6bit. Every string should be converted to an ASCII char. Therefore the Sixbit ASCII Code should be used.
Now I have a table with all the possible chars and the binary code for it. My first idea was to convert the binary string to the char by using a switch case and define a rule for every possibility, but this can't be the best option.
Is there some kind of a function, which I can use to convert this automatically and that I don't have to write a method with the switch?
public byte sixBitFromAscii(char asciiChar) {
if (asciiChar >= 0x60) {
System.out.println("Invalid character " + asciiChar);
return 0;
}
else {
return (byte)(asciiChar - 0x20);
}
}
public char asciiFromSixBit(byte sixBit) {
return (char) (sixBit + 0x20);
}
Ok, thanks to the clarification, and your posting the actual table, this becomes really simple. With the charset sorted, we can just convert directory and index into the array. Keep in mind, if you input was a String of 0/1s, you'd have to do some bit twiddling to get value (named n in this code). Otherwise, it would be the same.
public class sixbit {
static final char[] CHARSET =
{'#','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','[','\\',']','^',
'_',' ','!','"','#','$','%','&','\'','(',')','*','+',',','-',
'.','/','0','1','2','3','4','5','6','7','8','9',':',';','<',
'=','>','?'};
public static void main(String[] args) {
// Sample String of length 48, maybe up of 1s and 0s
String input = "010011010100000001000011001011001111010110010010" ;
System.out.println(input);
String[] parts = splitInput(input); // Split into 6-bit pieces
for(String sixbit: parts) {
int n = Integer.parseUnsignedInt(sixbit, 2);
System.out.printf("%s -> %c \n", sixbit,CHARSET[n]);
}
}
private static String[] splitInput(String input) {
String[] parts = new String[8]; // 48 bits, 6 bits each means we get 8 characters;
int current_part = 0;
int current_bit = 0;
StringBuilder sb;
while(current_bit < 48) {
sb = new StringBuilder();
for(int i=0; i < 6; i++) {
sb.append(input.charAt(current_bit));
current_bit++;
}
parts[current_part] = sb.toString();
current_part++;
}
return parts;
}
}
old version
Other than the loadLookupTable() method only including some randomly tossed together entries your table, this should do what you want.
import java.util.*;
public class sixbit {
static Map<String,Character> lookup = new HashMap<String,Character>();
public static void main(String[] args) {
loadLookupTable();
// Sample String of length 48, maybe up of 1s and 0s
String input = "111000111001100110101000110000110100111011110111" ;
System.out.println(input);
String[] parts = splitInput(input); // Split into 6-bit pieces
for(String sixbit: parts) {
char ch = lookup.get(sixbit); // Lookup each 6-bit String to get the corresponding character.
System.out.printf("%s -> %c \n", sixbit, ch);
}
}
private static String[] splitInput(String input) {
String[] parts = new String[8]; // 48 bits, 6 bits each means we get 8 characters;
int current_part = 0;
int current_bit = 0;
StringBuilder sb;
while(current_bit < 48) {
sb = new StringBuilder();
for(int i=0; i < 6; i++) {
sb.append(input.charAt(current_bit));
current_bit++;
}
parts[current_part] = sb.toString();
current_part++;
}
return parts;
}
private static void loadLookupTable() {
/* For each bit string you have in your table, add the corresponding character. It would be shorter code,
* and a touch faster to load this from an array, but it would take a bit of thought and wouldn't be as clear.
* Grab enough to work for this example, so that this program works. Just need to make sure the full lookup is loaded
* properly.
*/
lookup.put("100110", 'a');
lookup.put("100111", 'b');
lookup.put("101000", 'c');
lookup.put("110000", 'k');
lookup.put("110100", 'o');
lookup.put("110111", 'r');
lookup.put("111000", 's');
lookup.put("111001", 't');
// and so on...
lookup.put("111011", 'v');
lookup.put("111100", 'w');
lookup.put("111101", 'x');
lookup.put("111110", 'y');
lookup.put("111111", 'z');
}
}
Break the String into bytes (6-bits each with 2 bits of padding). Then just use an array mapping the byte values to the ASCII char value.
edit Ok, I misunderstood your question as you having raw binary data. Apparent you have a String of 1s and 0s, like "1010111" of length 48. The actual implementation is very different (and a lot easier). See my other answer. Sorry for the confusion.
I tried multiple versions, including several solutions found here on StackOverflow, but I always get numbers instead of the characters in the console. For a homework in my uni, we need to invert the characters in a string. But creating the new string seems to be not so easy.
I tried using a StringBuilder,
StringBuilder builder = new StringBuilder();
// ...
builder.append(c); // c of type char
String concatenation,
System.out.print("" + c); // c of type char
and even String.valueOf(),
System.out.print(String.valueOf(c)); // c of type char
and each of them again with explicit conversion to char. But I always get the ordinal number of the characters in a sequence instead of the actual characters as output in the console. How do I correctly build a new string from chars?
/**
* Praktikum Informatik - IN0002
* Arbeitsblatt 02 - Aufgabe 2.6 (Buchstaben invertieren)
*/
public class H0206 {
public static String readLine() {
final StringBuilder builder = new StringBuilder();
try {
// Read until a newline character was found.
while (true) {
int c = System.in.read();
if (c == '\n')
break;
builder.append(c);
}
}
catch (java.io.IOException e) {
; // We assume that the end of the stream was reached.
}
return builder.toString();
}
public static void main(String[] args) {
// Read the first line from the terminal.
final String input = readLine();
// Create a lowercase and uppercase version of the line.
final String lowercase = input.toLowerCase();
final String uppercase = input.toUpperCase();
// Convert the string on the fly and print it out.
for (int i=0; i < input.length(); ++i) {
// If the character is the same in the lowercase
// version, we'll use the uppercase version instead.
char c = input.charAt(i);
if (lowercase.charAt(i) == c)
c = uppercase.charAt(i);
System.out.print(Character.toString(c));
}
System.out.println();
}
}
The problem I see with the sample code you provided is here:
int c = System.in.read();
if (c == '\n')
break;
builder.append(c);
The way you call the method, Stringbuilder.append(int) will be called. As the javadoc says, "the overall effect is exactly as if the argument were converted to a string by the method String.valueOf(int), and the characters of that string were then appended to this character sequence". Casting the integer-value to char like this will result in the desired behavior:
int c = System.in.read();
if (c == '\n')
break;
builder.append((char) c);
Here is a sample how to invert a String, there is another options, i think this one is more didacticism
public static void main(final String[] args) {
String text = "This is a string that will be inverted";
char[] charArray = text.toCharArray();
char[] invertedCharArray = new char[charArray.length];
for (int i = 1; i <= charArray.length; i++) {
char c = charArray[charArray.length - i];
invertedCharArray[i - 1] = c;
}
System.out.println(text);
System.out.println(new String(invertedCharArray));
}
try { // Read until a newline character was found.
while (true) {
int c = System.in.read();
if (c == '\n') break;
builder.append(c);
}
From the sample you gave, I can see that this is causing the problem. Because you are reading the char input as an int, it converts the char to its ordinal value so it can be stored (and therefore used) as an integer.
In public final class StringBuilder you're calling append(int i), which returns int. If int c = System.out.read();
is required for this to be declared as an integer, you can cast c to a char.
char ch = (char)c;
builder.append(ch)
If needed, this leaves c as an integer and stores its "original value" (What it was before it was turned into an int, i.e. the key pressed) in a variable if needed. If you only need to add it to the string, without reusing it for any reason, you can cast c to a char directly with append((char) c).
So I have created this program:
class Input {
public static void main(String[] args) throws Exception {
String hexa;
hexa = "";
int pituus;
pituus = hexa.length();
int i = 1;
char luku;
char luku2;
while (i < pituus) {
luku = hexa.charAt(i);
luku2 = hexa.charAt(i - 1);
luku++;
if (luku == 'G') {
luku = '0';
luku2++;
} else if (luku == ':')
luku = 'A';
if (luku2 == '8')
luku2 = '0';
System.out.print(luku2);
System.out.print(luku);
i += 2;
}
System.out.println();
}
}
As you can propably tell, it prints the original hex string, but adds 1 to every pair of characters, and I want the maximum value of the pairs to be 7F. This program however is only beginning, and to proceed further I need a string with all the characters printed. Is that possible?
To create Strings dynamically you can use StringBuilder. Just append characters to it like
StringBuilder sb = new StringBuilder();// builder is empty now
// some logic
for (char ch = 'a'; ch <= 'z'; ch++) {
// for this example we will just add all lower-case
// characters to builder
sb.append(ch);
}
// after all characres are placed in builder
// lets convert it to string
String alphabet = sb.toString();
// and see what we got
System.out.println(alphabet);
Output: dynamically generated alphabet
abcdefghijklmnopqrstuvwxyz
public static String basicEncrypt(String s) {
String toReturn = "";
for (int j = 0; j < s.length(); j++) {
toReturn += (int)s.charAt(j);
}
//System.out.println("Encrypt: " + toReturn);
return toReturn;
}
Is there any way to reverse this to find the original string? Much appreciated.
Under the assumption that you only use ASCII characters (32-255 codes) the algorithm is simple:
Take the first character of input
If it's 1 or 2 - take and cut off next two digits and convert to character
If it's any other character - take and cut off next digit and convert to character
Go to 1. if some input left
Here is a quick'n'dirty Scala implementation:
def decrypt(s: String): String = s.headOption match {
case None => ""
case Some('1') | Some('2') => s.substring(0, 3).toInt.toChar + decrypt(s.substring(3))
case Some(_) => s.substring(0, 2).toInt.toChar + decrypt(s.substring(2))
}
Yes, if taken in account that your original string consists of characters between and including (32) and unicode charcode 299, see http://www.asciitable.com/
Psuedo code
ret=<empty string>
while not end of string
n=next number from string
if n<3 charcode= n + next 2 numbers
else
charcode=n + next number
ret=ret + character(charcode)
end while
Charcodes under space (newlines and carriage returns)and above 299 will thwart this algorithm. This algorithm can be fixed to include characters up to charcode 319.
private static String basicDecrypt(String s) {
String result = "";
String buffer = "";
for (int i = 0; i < s.length(); i++) {
buffer += s.charAt(i);
if ((buffer.charAt(0) == '1' && buffer.length() == 3) || (buffer.charAt(0) != '1' && buffer.length() == 2)) {
result += (char) Integer.parseInt(buffer);
buffer = "";
}
}
return result;
}
This is a very basic decryption method. It will only work for [A-Za-z0-9]+ US ASCII.
Just for the fun of it, another couple of versions; Java, US-ASCII only, chars 0x14-0xc7;
public static String basicDecrypt(String input)
{
StringBuffer output = new StringBuffer();
Matcher matcher = Pattern.compile("(1..|[2-9].)").matcher(input);
while(matcher.find())
output.append((char)Integer.parseInt(matcher.group()));
return output.toString();
}
For 0x1e-0xff, replace the regex with "([12]..|[3-9].)"
...and a somewhat briefer Linq'y C# version.
private static string BasicDecrypt(string input)
{
return new string(Regex.Matches(input, "(1..|[2-9].)").Cast<Match>()
.Select(x => (char) Int32.Parse(x.Value)).ToArray());
}