beginner here! I was just wondering if anyone could help? I am currently writing a Encryption/Decryption programme in Java and need to reverse binary which is inputted. I have managed to do encrypt it into binary, however, I am struggling to now decrypt it (e.g - The word HELLO has been encrypted , but I now need to create a function so that it can read the binary and change it back to the text.)
Any help would be appreciated! This is the code I used for my original binary cipher in the encryption part.
String temp="";
for(int i=0;i<message.length();i++)
{
temp=Integer.toBinaryString(message.charAt(i));
for(int j=temp.length();j<8;j++)
{
temp="0"+temp;
}
encryptText+=temp+" ";
}
I have tried various different measures but being as I have just started out a little guidance would be hugely appreciated!
If you're just trying to get a fixed-length Binary String, try this:
private static String toBinaryString(final int value) {
final String binaryString = Integer.toBinaryString(value);
final char[] lead = new char[Integer.SIZE - binaryString.length()];
Arrays.fill (lead, '0');
return String.valueOf(lead).concat(binaryString);
}
If there would be no space between every group of 8 bits 0/1:
for (int i = 0; i + 7 < message.length(); i += 8) {
String temp = message.substring(i, i + 8);
int c = Integer.parseInt(temp, 2); // Base 2, binary
decryptText += (char)c;
}
Space separated:
for (String temp : message.split(" ")) {
if (!temp.isEmpty()) {
int c = Integer.parseInt(temp, 2); // Base 2, binary
decryptText += (char)c;
}
}
Related
I have a text file, which is divided in 3 part, and now I want to convert this divided block to binary format and store in database.
Please help me to solve this problem.
Thanks.
String firstblock = “If debugging is thae process of removing software bugs, then programming must be the process of putting them in. Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.”;
and I need firstblock in binary form.
String firstblock = “If debugging is thae process of removing software bugs, then programming must be the process of putting them in. Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.”;
byte[] bytes = firstblock.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes)
{
int val = b;
for (int i = 0; i < 8; i++)
{
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
System.out.println(binary);
and you can check it binary to string
Use getBytes() method.
See the below
String text = "Hello World!";
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
Update:
Try with below code:
String s = "foo";
byte[] bytes = s.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes)
{
int val = b;
for (int i = 0; i < 8; i++)
{
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
System.out.println("'" + s + "' to binary: " + binary);
Reference :
Convert A String (like testing123) To Binary In Java
String s = "foo";
byte[] bytes = s.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes)
{
int val = b;
for (int i = 0; i < 8; i++)
{
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
System.out.println("'" + s + "' to binary: " + binary);
you try with this code if you want to use online tool
An English to binary translator is a tool that can convert text
written in the English language into a sequence of 0s and 1s, which is
known as binary code. This is the language that computers understand
and use to process and store data.
Here is an example of how it would work:
Input: "Hello" Output: "01001000 01100101 01101100 01101100 01101111"
The translator would take the word "Hello" and convert each letter
into its corresponding 8-bit binary code representation.
First off, here is my code so far
public int encrypt() {
/* This method will apply a simple encrypted algorithm to the text.
* Replace each character with the character that is five steps away from
* it in the alphabet. For instance, 'A' becomes 'F', 'Y' becomes '~' and
* so on. Builds a string with these new encrypted values and returns it.
*/
text = toLower;
encrypt = "";
int eNum = 0;
for (int i = 0; i <text.length(); i++) {
c = text.charAt(i);
if ((Character.isLetter(c))) {
eNum = (int) - (int)'a' + 5;
}
}
return eNum;
}
(text is the inputted string by the way. And toLower makes the string all lower case to make it easier converting.)
I got most of my assignment done, but one part of it is tasking me with moving every letter inputted 5 spaces over. A becomes F, B becomes G, etc.
So far from I got the letter converted to a number, but I am having trouble adding to it and then returning it back to a letter.
When I run the program and I enter my input such as "abc" I get '8'. It just adds them all up.
Any help would be much appreciated, and I can post the full code if necessary.
Few issues -
First of all - eNum = (int) - (int)'a' + 5; you do not need the first (int) - i believe, you can just do - eNum = (int)c + 5; . Your expression would always result in a negative integer.
Instead of returning eNum you should convert it to character and add it to a string and return the string at end (or you can create a character array of same length as string , keep storing the characters in the array, and return a string created from the character array).
Instead of using a in the condition , you should use c which denotes the current character at the ith index.
I am guessing not all of the variables in your code are member variables (instance variables) of the class , so you should define them with a datatype in your code.
Example changes to your code -
String text = toLower; //if toLower is not correct, use a correct variable to get the data to encrypt from.
String encrypt = "";
for (int i = 0; i <text.length(); i++) {
char c = text.charAt(i);
if ((Character.isLetter(c))) {
encrypt += (char)((int)c + 5);
}
}
return encrypt;
//Just a quick conversion for testing
String yourInput = "AbC".toLowerCase();
String convertedString = "";
for (int i = 0; i <text.length(); i++) {
char c = yourInput.charAt(i);
int num = Character.getNumericValue(c);
num = (num + 5)%128 //If you somehow manage to pass 127, to prevent errors, start at 0 again using modulus
convertedString += Integer.toString(num);
}
System.out.println(convertedString);
Hope this is what you're looking for.
Try something like this, I believe this has several advantages:
public String encrypt(String in) {
String workingCopy = in.toLowerCase();
StringBuilder out = new StringBuilder();
for (int i = 0; i < workingCopy.length(); i++) {
char c = workingCopy.charAt(i);
if ((Character.isLetter(c))) {
out.append((char)(c + 5));
}
}
return out.toString();
}
This code is a little bit verbose, but perhaps then it is easier to follow. I introduced the StringBuilder because it is more efficient than doing string = string + x
Acording to a other question made here Split a Hex String without spaces and flip it, I write this new question more clearly here.
I have an Hex String like this:
Hex_string = 2B00FFEC
What I need is to change the order of the Hex String to start from the latest characters, so this would be like this:
Fliped_hex_string = ECFF002B
In the other question I asked a way to achieve this using the .split() method. But there should be another way to get this in a better way.
As simple as you can is
String s = "2B00FFEC";
StringBuilder result = new StringBuilder();
for (int i = 0; i <=s.length()-2; i=i+2) {
result.append(new StringBuilder(s.substring(i,i+2)).reverse());
}
System.out.println(result.reverse().toString()); //op :ECFF002B
OP constrains the character length to exactly 8 characters in comments.
A purely numeric answer (inspired from idioms to convert endianness); saves going to and from strings
n is an int:
int m = ((n>>24)&0xff) | // byte 3 to byte 0
((n<<8)&0xff0000) | // byte 1 to byte 2
((n>>8)&0xff00) | // byte 2 to byte 1
((n<<24)&0xff000000); // byte 0 to byte 3
If you need to convert this to hexadecimal, use
String s = Integer.toHexString(m);
and if you need to set n from hexadecimal, use
int n = (int)Long.parseLong(hex_string, 16);
where hex_string is your initial string. You need to go via the Long parser to allow for negatives.
You could do something like:
String a = "456789AB";
char[] ca = a.toCharArray();
StringBuilder sb = new StringBuilder(a.length());
for (int i = 0; i<a.length();i+=2)
{
sb.insert(0, ca, i, 2);
}
This also extends to longer Strings if needed
Perhaps you should try something as simple as this:
public static String flip(final String hex){
final StringBuilder builder = new StringBuilder(hex.length());
for(int i = hex.length(); i > 1; i-=2)
builder.append(hex.substring(i-2, i));
return builder.toString();
}
public static void main(String args[]){
System.out.println(flip("2B00FFEC"));
}
The output is: ECFF002B
Next time you ask a question, perhaps you should show us some code you've written used in order to solve your problem (and then ask us why your code doesn't work, not your problem). You will not learn anything from us just providing answers without you knowing how they work.
This method seems to do what you want
String changeHexOrder(String s) {
char[] arr = s.toCharArray();
char tmp;
//change positions of [i, i + 1 , , , , , ,length - i - 2, length - i - 1]
for (int i = 0; i < arr.length / 2; i += 2) {
tmp = arr[i];
arr[i] = arr[arr.length-i-2];
arr[arr.length-i-2] = tmp;
tmp = arr[i+1];
arr[i+1] = arr[arr.length-i-1];
arr[arr.length-i-1] = tmp;
}
return new String(arr);
}
This worked for me
StringBuilder lsbToMsb=new StringBuilder();
for(int i=input.length();i>0;i-=2)
{
lsbMsb.append(lsbToMsb.substring(i-2,i));
}
String lsbMsb=lsbMsb.toString();
I am trying to pick up cryptography and had been trying this exercise
Write a program (preferably Java) to generate a one-time pad, which is a relatively large file of all
random data (say 1 MB). The program should also be able to encrypt/decrypt files based on the
generated one time pad.
Tip: use the following test vector to check if your program does encryption correctly.
Plaintext (ASCII): Every cloud has a silver lining
OTP (HEX): 6dc72fc595e35dcd38c05dca2a0d2dbd8e2df20b129b2cfa29ad17972922a2
ciphertext (HEX): 28b14ab7ecc33ea157b539ea426c5e9def0d81627eed498809c17ef9404cc5
I have tried to generate a one time pad using random number generator as I need to convert them to HEX form. and I am pretty sure I am confused or not tackling it the right way
public static void oneTimePad()
{
Random ran = new Random();
String s = "0123456789ABCDEF";
for(int i = 0; i < 100; i++)
{
System.out.print(s.charAt(ran.nextInt(s.length())));
}
}
Above would be my one time pad, and I was wondering how any idea how I could implement the encryption using the one time pad and decrypting it.
Here you have a full working example:
// convert secret text to byte array
final byte[] secret = "secret".getBytes()
final byte[] encoded = new byte[secret.length];
final byte[] decoded = new byte[secret.length];
// Generate random key (has to be exchanged)
final byte[] key = new byte[secret.length];
new SecureRandom().nextBytes(key);
// Encrypt
for (int i = 0; i < secret.length; i++) {
encoded[i] = (byte) (secret[i] ^ key[i]);
}
// Decrypt
for (int i = 0; i < encoded.length; i++) {
decoded[i] = (byte) (encoded[i] ^ key[i]);
}
assertTrue(Arrays.equals(secret, decoded));
For the one time pad you need a byte array, not hexadecimals. The hexadecimals are only required for displaying data (we tend to have trouble reading bits). You can use the Apache Commons libraries (codec package) to create hexadecimals from byte arrays, or back if you want to decode the test vectors from hexadecimals to bytes.
You should use a secure random number generator, not Random. So use new SecureRandom() instead. To generate random data, first create a byte array, then call nextBytes() on the random number generator. There is not need to generate integers.
First here is a OTP algorithm specified called HOTP which is a standard RFC. Almost all other OTP are propriety and we don't know the algorithm for those.
https://www.rfc-editor.org/rfc/rfc4226
There is some java code in there you can use to learn how its done. Second if you are going to do encryption don't use Random. Random is nice for psuedo random, but if you really want a good source of random data you need to adopt SecureRandom. That's a much better source of random numbers that are suitable for cryto algorithms.
For converting things to Hex you can easily use
http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html#toString(int)
Or any of the varieties Long.toString(value,radix), Integer.toString(value,radix), or Byte.toString(value,radix).
byte[] bytes = ...;
for( int i = 0; i < bytes.length; i++ ) {
System.out.println( Integer.toString( bytes[i], 16 );
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one_time_pad
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(" TRYING\n");
Console.WriteLine("Enter : ");
int input= int.Parse( Console.ReadLine());
//random num generation
Random rnd = new Random();
int random = rnd.Next(1,10);
//binary conversion
string binary = Convert.ToString(random,2);
string inbinary = Convert.ToString(input,2);
Console.WriteLine("Data : " +input +" Binary : " + inbinary);
Console.WriteLine(" Key : " +random + " Binary : " + binary);
// taking xor
int Ghul = input ^ random;
//binary conversion
string intcon = Convert.ToString(Ghul,2);
Console.WriteLine("Encrypted : " + intcon);
Console.WriteLine(":)");
Console.Read();
}
}
}
https://en.wikipedia.org/wiki/One-time_pad
public static String crypt(String string, String keyString) {
// convert secret text to byte array
byte[] bytes = string != null ? string.getBytes() : new byte[0];
int size = bytes != null ? bytes.length : 0;
final byte[] encoded = new byte[size];
final byte[] key = keyString != null ? keyString.getBytes() : new byte[0];
// loop on input bytes
for (int i = 0; i < size; i++) {
// shift key index
// (we assume key can be smaller or equal if larger then adjust)
int keyi = i >= keySize ? size % (keySize-1) : i;
// pad
encoded[i] = (byte) (bytes[i] ^ key[keyi]);
}
return new String(encoded);
}
public static void test(String string, String keyString) {
String encrypt = crypt(string, keyString);
String decrypt = crypt(encrypt, keyString);
assert(string.equals(decrypt));
}
test("test","1234");
test("test","123");
ps. you can refactor method by pull strings up and replace with bytes
public static byte[] crypt(byte[] bytes, byte[] key) {
int size = bytes != null ? bytes.length : 0;
final byte[] encoded = new byte[size];
int keySize = key != null ? key.length : 0;
// loop on input bytes
for (int i = 0; i < size; i++) {
// shift key index (assuming key <= bytes)
int keyi = i >= keySize ? size % (keySize-1) : i;
// pad
encoded[i] = (byte) (bytes[i] ^ key[keyi]);
}
return encoded;
}
<dependency>
<groupId>work.eddiejamsession</groupId>
<artifactId>jam-one-time-pad</artifactId>
<version>0.67</version>
</dependency>
JamOneTimePad pad = new JamOneTimePad();
String heyEncrypted = pad.encrypt("hey"); //encodes additionally in base64 for url safety
String heyDecrypted = pad.decrypt(heyEncrypted);
System.out.println(heyDecrypted.equals("hey"));
Output: true
I am probably overlooking something silly, but I've never had to deal with binary in code and thought it'd be a good idea to practice it in an encryption program, for kicks.
Long story short, I'm able to convert a string into binary (in the form of a string), but can't figure out how to do the reverse.
Right now, I have something like this:
public static String bytesToString(String bytes){
int i = bytes.length()/8;
int pos = 0;
String result = "";
for(int j=0; j<i; j++){
String temp = bytes.substring(pos,pos+8);
byte b = (byte) Integer.parseInt(temp);
result = result + Byte.toString(b);
pos++;
}
System.out.println("Result: " + result);
return result;
}
I think the bytes are being parsed as literal numbers. What am I missing?
Edit: To clarify, I will previously have parsed a string of text into bits and written them to a string. I want to split this string into bytes and parse them back into letters. It would take "011010000110010101111001" and return "hey".
How about using Integer.parseInt(text, 2)? As in,
public static int binaryToInt(String binary)
{
return Integer.parseInt(binary, 2);
}
I'm not sure why your binaryToString method both takes and returns a string.
Integer.parseInt(temp) will attempt to read temp as a number and return the corresponding int. For example, Integer.parseInt("123") returns 123
EDIT: Be aware that the binary value of a character or text depends on the encoding you are using. For example "hi" is 0110100001101001 in ASCII but it may not in UTF-16 or UTF-32. And Java encodes characters into UTF-16 characters: see http://download.oracle.com/javase/6/docs/api/java/lang/String.html
(for this reason Java chars are 16-bit unsigned integers).
So your bytesToString method must treat input differently depending on the encoding of the input. Or you may write it specifically for ASCII characters, and maybe rename it to, say, asciiBytesToString
You'd better see:
constructor String(byte[])
http://download.oracle.com/javase/6/docs/api/java/lang/String.html
Integer.parseInt(String s, int radix) http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html
public class BinaryStringToChars {
public static void main(String[] args) {
String bin = "011010000110010101111001";
StringBuilder b = new StringBuilder();
int len = bin.length();
int i = 0;
while (i + 8 <= len) {
char c = convert(bin.substring(i, i+8));
i+=8;
b.append(c);
}
System.out.println(b.toString());
}
private static char convert(String bs) {
return (char)Integer.parseInt(bs, 2);
}
}
You need to advance 8 digits at a time, not digit by digit. Otherwise you are reusing bits. Also, you need to tell Integer.parseInt() what radix you want to use, since parseInt(String val) cannot really detect binary (you want Integer.parseInt(String val, int radix). You also need to choose a character encoding to convert bytes into characters (they are not the same thing!). Assuming ISO-8859-1 is ok:
public static String bytesToString(String bytes){
int i = bytes.length()/8;
int pos = 0;
String result = "";
byte[] buffer = new byte[i];
for(int j=0; j<i; j++){
String temp = bytes.substring(pos,pos+8);
buffer[j] = (byte) Integer.parseInt(temp, 2);
pos+=8;
}
result = new String(buffer, "ISO-8859-1");
System.out.println("Result: " + result);
return result;
}