Encode a String into a BigInteger then decode back to String
Asked Answered
F

2

6

I found an answer that almost solves my problem: https://mcmap.net/q/1414267/-convert-biginteger-to-shorter-string-in-java

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.

Feudist answered 29/2, 2012 at 15:5 Comment(8)
Is there a way of encoding technique/method for a String to a BigInteger then back to a String?: yes.Fundamentalism
Thanks, could you tell me how please?Feudist
What I mean is there are aleph-null ways to do this, e.g., you could convert the String to its ascii bytes and then back again, or via many other simpler or more complex encoding techniques. Could you be a little more specific?Fundamentalism
You need a bijective encoding function.Decontrol
For instance, isn't something like this what happens all the time when we stream text from wherever? The Strings get converted to bits (numbers), are transmitted, and then converted back.Fundamentalism
i've edited my question to explain the purpose, I hope this helpsFeudist
What's wrong with String.getBytes()? Most encryption implementations accept byte arrays not BigIntegers, I thinkCriswell
the reason I am trying to use a BigInteger is because I am going to use the BigInteger in a calculation to create cipher text. I am using RSA but I am not using the built in RSA algorithm function.Feudist
E
12

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?

Eyrir answered 29/2, 2012 at 15:33 Comment(9)
Thank you, I have only just started using BigIntegers I didn't realise you could do this The next step in my function is: bigInt.pow(Public_Key) % ModulusFeudist
ok. Note that you can get an smaller BigInteger output by providing a different radix. For example, bigInt.toString(16). FYIEyrir
Cipher_Text = bigInt.pow(Public_Key) % ModulusFeudist
Thanks again, Yanick Rochon. I'll give it a goFeudist
@RichardCypher Use bigInt.modPow(Public_Key,Modulus) to keep intermediate BigIntegers moderately small.Ellynellynn
@YanickRochon is this guaranteed to be unique? Can two strings be encoded to same BigInteger. My gut tells no. but wanted to confirm.Skiagraph
@Skiagraph of course! Every string will be unique, since BigInteger takes the raw bytes and simply does a "binary to base10" conversion. If you think that two BigIntegers can have the same value for two different strings, then somewhere in the universe, someone forgot to test two different numeric values for equality :) Also, do not confuse encoding with encryption.Eyrir
Shorter encoded strings can be had by using a larger raddix. String str = "some cool test string with special characters!?%$%(*$^$"; String encoded = new BigInteger(str.getBytes()).toString(22) and String decoded = new String (new BigInteger(encoded, 22).toByteArray()) raddix can be any value from 2 to 36.Excretory
Wrong answer. The length would be changed if the original text is "\0Hello world!".Synsepalous
S
0

The approach to pass bytes directly to new BigInteger as described in https://mcmap.net/q/1660175/-encode-a-string-into-a-biginteger-then-decode-back-to-string 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() + ")");
  }
}
Synsepalous answered 25/4 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.