Jake Graham Arnold
Jake Graham Arnold

Reputation: 1446

Encode a String into a BigInteger then decode back to String

I found an answer that almost solves my problem: https://stackoverflow.com/a/5717191/1065546

This answer demonstrates how to encode a BigInteger into a String then back into a BigInteger using Base64 encodings which uses Apache commons-codec.

Is there a way of encoding technique/method for a String to a BigInteger then back to a String? if so would someone please explain how to use it?

      String s = "hello world";
      System.out.println(s);

      BigInteger encoded = new BigInteger( SOME ENCODING.(s));
      System.out.println(encoded);

      String decoded = new String(SOME DECODING.(encoded));
      System.out.println(decoded);

Print:

      hello world
      830750578058989483904581244
      hello world

(The output is just an example and hello world doesn't have to decode to that BigInteger)

EDIT

More specific:

I am writing a RSA algorithm and I need to convert a message into a BigInteger so that I can then encrypt the message with the public key (send message) and then decrypt the message with the private key and then convert the number back into a String.

I would like a method of conversion that could produce the smallest BigInteger as I was planning on using binary until I realised how ridiculouslybig the number would be.

Upvotes: 6

Views: 19923

Answers (2)

Yang Bo
Yang Bo

Reputation: 3728

The approach to pass bytes directly to new BigInteger as described in https://stackoverflow.com/a/9501964/955091 would discard starting \0s unexpectedly.

import java.math.BigInteger;

public class Main {
 
  public static void main(String[] args) {
    String text = "\0\0Hello world!";

    // Output: Test string = Hello world! (length = 14)
    System.out.println("Test string = " + text + " (length = " + text.length() + ")");

    // convert to big integer
    BigInteger bigInt = new BigInteger(text.getBytes());
    System.out.println(bigInt.toString());

    // convert back
    String textBack = (new String(bigInt.toByteArray()));

    // Output: And back = Hello world! (length = 12)
    System.out.println("And back = " + textBack + " (length = " + textBack.length() + ")");
  }
}

You can see text.length() and textBack.length() are different.

To protect the starting \0's, we can prepend a magic header:

import java.math.BigInteger;

public class Main {

  private static final String MAGIC = "MAGIC";
  
  public static void main(String[] args) {
    String text = "\0\0Hello world!";
    System.out.println("Test string = " + text + "(length = " + text.length() + ")");

    // convert to big integer
    BigInteger bigInt = new BigInteger((MAGIC + text).getBytes());
    System.out.println(bigInt.toString());

    // convert back
    String textBack = (new String(bigInt.toByteArray())).substring(MAGIC.length());
    System.out.println("And back = " + textBack + "(length = " + textBack.length() + ")");
  }
}

Upvotes: 0

Yanick Rochon
Yanick Rochon

Reputation: 53606

I don't understand why you want to go through complicated methods, BigInteger already is compatible with String :

// test string
String text = "Hello world!";
System.out.println("Test string = " + text);

// convert to big integer
BigInteger bigInt = new BigInteger(text.getBytes());
System.out.println(bigInt.toString());

// convert back
String textBack = new String(bigInt.toByteArray());
System.out.println("And back = " + textBack);

** Edit **

But why do you need BigInteger while you can work directly with the bytes, like DNA said?

Upvotes: 12

Related Questions