BigInteger class with non-ascii characters in Java - java

I've been working on a little application which grabs strings embedded within a picture, which in turn are used to calculate 2 big integers for use in a key exchange system. However, when I try and read the strings from a properties file, and implement them into a bigint:
String primeStr = "ekoeaokimcgmigcqu{uq{y}sw}ywsAEKOEAOKIMCGMIGCQU[_UQ_[Y]SW]YWS!%+/%!/+)-#'-)'#15;?51?;9=37=973"
BigInteger prime = new BigInteger(this.primeStr,10);
I'm thrown an error about the string not being correct. My question is how would I solve the issue so I can use that string within the app?

The String constructor of BigInteger expects a number, if your primeStr variable somehow encodes a number you'll have to decode it first before passing it to BigInteger.

Related

get binary int, java

I want to pull an int from a getMethod() that is in binary format. Does anyone know how to use: int i = 0b10101010;(taken from a previous post on Stack Overflow thank you all) with a variable.
int i = 0bgetMethod(); does not work in any of the multiple ways I have tried it (0b + var, etc). I do not have the actual value, so I cannot hard code the 1's & 0's.
Any help would be appreciated. This is for an assembler, this binary number is selecting the register in the register file, passed in string format to preserve it until I parse it.
A digital computer stores all int(s) in binary (even those you encode in decimal). You can use Integer.toBinaryString(int) to see the binary representation of any int.
If you need to parse a binary String, you can use Integer.parseInt(String, int) where the first argument is the String to be parsed and second argument is a radix (for binary that would be 2).
code: int i = Integer.parseInt(Micro.RegSel, 2); produces an error(the method is not applicable for enumbody).
Micro.RegSel is an enum implements enumbody that results in a string of 4 1's & 0's. If I simply print it, it prints out dropping all the leading zeros. I need the leading zeros. My code needs a total of 32bits, and this is part of it.
one of the switch statements has: Micro.RegSel.setFourBit("0011"); This will print "11". printing the string directly from the enum: 0011
int i = Integer.parseInt(Micro.RegSel.getFourBit().toString(), 2); produces a java.lang.NumberFormatException even though Micro.RegSel.getFourBit().toString() prints all 4 digits
After trying several options (that's where I asked my question) and reading the stack trace, I realized that the problem was the default was "xxxx" for the opcodes that do not select a register.
so I rewrote it like this:
int i = 0;
String j = Micro.RegSel.getFourBit().toString();
if(j.matches("[\d]")){
i = Integer.parseInt(j, 2);
}
It works like I need it to. Thanks

Prevent Int from changing 012345 to 5349 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Integer with leading zeroes
The program I am coding requires me to label an item with an inventory number of 012345 and store it in a int variable.
This is a stripped down example of what I am doing:
int test = 012345;
System.out.println(test);
this prints as:
5349
How do I get it to print out as 012345 rather than 5349?
EDIT: I am entering this into the parameter of a constructor for a custom class i am initializing. Then I use a method to return what the current number is, then print it to the terminal window.
You get a wrong number because when you prepend zero to an integer literal, Java interprets the number as an octal (i.e. base-8) constant. If you want to add a leading zero, use
int test = 12345;
System.out.println("0"+test);
You can also use the formated output functionality with the %06d specifier, like this:
System.out.format("%06d", num);
6 means "use six digits"; '0' means "pad with zeros if necessary".
As already said, int value with leading zero is considered as octal value. If you don't need to have test as int, why not make it string? Like
String test= new String("012345");
And if you want to use int for test, you can do not prepend 0, rather just use the number and prepend 0 at the time of printing.
In case if you're wondering how will you find how many leading zero are to be prepended, you may do like this
int lengthOfItemID=6;
int test=12345;
String test1=new String("000000"+test);
System.out.println(test1.substring(test1.length()-lengthOfItemID));
Pardon syntax mistakes, been years I last worked with java.
You can get the right result by using Integer.parseInt. That will make your string into a decimal string. (found here). The JAVA API here states that it takes a string and returns a signed decimal.

A two way String hash function

I want to get a unique numeric representation of a String. I know there are lots of ways of doing this, my question is which do you think is the best? I don't want to have negative numbers - so the hashcode() function in java is not so good, although I could override it ... but I'd rather not since I am not so confident and don't want to accidentally break something.
My Strings are all semantic-web URIS. The reason for the numeric representation is that when I display the data for a URI on a page I need something to pass into the query String or put into various fields in my javascript. The URI itself is too unwieldy and looks bad when you have a URI as a value in a URI.
Basically I want to have a class called Resource which will look like this
Resource{
int id;
String uri;
String value; // this is the label or human readable name
// .... other code/getters/setters here
public int getId(){
return id = stringToIntFunction();
}
private int stringToIntFunction(String uri){
// do magic here
}
}
Can you suggestion a function that would do this if:
It had to be two way, that is you could also recover the original string from the numeric value
It doesn't have to be two way
Also are there other issues that are important that I am not considering?
If you want it to be reversible, you're in trouble. Hashes are designed to be one-way.
In particular, given that an int has 32 bits of information, and a char has 16 bits of information, requiring reversibility means you can only have strings of zero, one or two characters (and even that's assuming that you're happy to encode "" as "\0\0" or something similar). That's assuming you don't have any storage, of course. If you can use storage, then just store numbers sequentially... something like:
private int stringToIntFunction(String uri) {
Integer existingId = storage.get(uri);
if (existingId != null) {
return existingId.intValue();
}
return storage.put(uri);
}
Here storage.put() would increase a counter internally, store the URI as being associated with that counter value, and return it. My guess is that that's not what you're after though.
Basically, to perform a reversible encryption, I'd use a standard encryption library having converted the string to a binary format first (e.g. using UTF-8). I would expect the result to be a byte[].
If it doesn't have to be reversible, I'd consider just taking the absolute value of the normal hashCode() result (but mapping Integer.MIN_VALUE to something specific, as its absolute value can't be represented as an int).
Hashes are one way only (that's part of the reason they have a fixed length regardless of the input size). If you need two-way, you're looking at something like Base64 encoding.
Why can't you have negative numbers? Where do the URIs come from? Are they in a database? Why not use the Database Key ID? If they are not in a database, can you generate them for the user given a set of variables/parameters? (So the query string only contains things like foo=1&bar=two and you generate the URL on the Server or JavaScript side)
Given all the remars done above (hash function is one way), I would go for 2 possible solutions:
Use some encrypting function to get a long string representing your URL (you'll get something like -> param=456ab894ce897b98f (this could be longer and/or shorter depending on the URL). See DES encryption for instance or base64url.
Keep track of the URLs in a database (could be also a simple file-based database such as SQLite). Then you'll effectively have an uint <=> URL equivalence.
"Unique representation" implies that the Java supplied string.hashcode would be useless - you'd soon come across two URIs that shared the same hashcode.
Any two-way scheme is going to result in an unwieldy string - unless you store the URIs in a database and use the record ID as your unique identifier.
As far as one-way goes - an MD5 hash would be considerably more unique (but by no means unique) than the simple hashcode - but might be verging on "unwieldy" depending on your definition!
Q1: If you want to recover the string from the number then you could use:
1a: an encryption of the string, which is going to be the same size, or longer, unless you zip the string first. This will give an array of random looking bytes, which could be displayed as Base-64.
1b: a database, or a map, and the number is the index of the string in the map/database.
Q2: The string does not have to be recoverable.
Various ideas are possible here. You can display the hash in hex or in Base-64 to avoid negative signs. The only non-alphanumeric characters in Base-64 are '+', '/' and '='. For an almost unique hash you will need something of cryptographic size, MD5 (128 bits), SHA-1 (160 bits) or SHA-2 (256 or 512 bits).
An MD5 hash looks like "d131dd02c5e6eec4693d9a0698aff95c" in hex; the larger the hash the less likely a collision is.
rossum

how to store mobile number in java?

I am trying to store the 10 digit mobile number in int, but it is saying that its out of range, how can i store in int, any help pls
There is no semantic value in storing it as a number - you won't be doing any numerical operations on it. You should store the value as a string.
A mobile number might start with a 0 (zero) therefore I wouldn't advice to store it as a number. My advice would be to store it as a String. Otherwise you should use a long.
What about a proper TelephoneNumber type class:
public interface TelephoneNumber
A simple re-usable entity class that defines attributes of a telephone number.
You'd better use String, but you can also use long or BigInteger.
But using String will allow you to store dashes or spaces between numbers.
Mobile numbers uses and E.164 numbering format for telephone or digital communications. You will have to use Strings as valid characters such as "+"/"-" can be found in mobile numbers.
Use a String, for for proper semantics I would wrap it in your own MobileNumber class.
Did you have a look at Java's BigInteger? Two possible references are:
Oracle BigInteger
Java Notes BigInteger
use Long or String instead of Integer. Or give us some code examples for what you are trying to do.

How does a person go about learning Java? (convert byte array to hex string)

I know this sounds like a broad question but I can narrow it down with an example. I am VERY new at Java. For one of my "learning" projects, I wanted to create an in-house MD5 file hasher for us to use. I started off very simple by attempting to hash a string and then moving on to a file later. I created a file called MD5Hasher.java and wrote the following:
import java.security.*;
import java.io.*;
public class MD5Hasher{
public static void main(String[] args){
String myString = "Hello, World!";
byte[] myBA = myString.getBytes();
MessageDigest myMD;
try{
myMD = MessageDigest.getInstance("MD5");
myMD.update(myBA);
byte[] newBA = myMD.digest();
String output = newBA.toString();
System.out.println("The Answer Is: " + output);
} catch(NoSuchAlgorithmException nsae){
// print error here
}
}
}
I visited java.sun.com to view the javadocs for java.security to find out how to use MessageDigest class. After reading I knew that I had to use a "getInstance" method to get a usable MessageDigest object I could use. The Javadoc went on to say "The data is processed through it using the update methods." So I looked at the update methods and determined that I needed to use the one where I fed it a byte array of my string, so I added that part. The Javadoc went on to say "Once all the data to be updated has been updated, one of the digest methods should be called to complete the hash computation." I, again, looked at the methods and saw that digest returned a byte array, so I added that part. Then I used the "toString" method on the new byte array to get a string I could print. However, when I compiled and ran the code all that printed out was this:
The Answer Is: [B#4cb162d5
I have done some looking around here on StackOverflow and found some information here:
How can I generate an MD5 hash?
that gave the following example:
String plaintext = 'your text here';
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
// Now we need to zero pad it if you actually want the full 32 chars.
while(hashtext.length() < 32 ){
hashtext = "0"+hashtext;
}
It seems the only part I MAY be missing is the "BigInteger" part, but I'm not sure.
So, after all of this, I guess what I am asking is, how do you know to use the "BigInteger" part? I wrongly assumed that the "toString" method on my newBA object would convert it to a readable output, but I was, apparently, wrong. How is a person supposed to know which way to go in Java? I have a background in C so this Java thing seems pretty weird. Any advice on how I can get better without having to "cheat" by Googling how to do something all the time?
Thank you all for taking the time to read. :-)
The key in this particular case is that you need to realize that bytes are not "human readable", but characters are. So you need to convert bytes to characters in a certain format. For arbitrary bytes like hashes, usually hexadecimal is been used as "human readable" format. Every byte is then to be converted to a 2-character hexadecimal string which you in turn concatenate together.
This is unrelated to the language you use. You just have to understand/realize how it works "under the hoods" in a language agnostic way. You have to understand what you have (a byte array) and what you want (a hexstring). The programming language is just a tool to achieve the desired result. You just google the "functional requirement" along with the programming language you'd like to use to achieve the requirement. E.g. "convert byte array to hex string in java".
That said, the code example you found is wrong. You should actually determine each byte inside a loop and test if it is less than 0x10 and then pad it with zero instead of only padding the zero depending on the length of the resulting string (which may not necessarily be caused by the first byte being less than 0x10!).
StringBuilder hex = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
if ((b & 0xff) < 0x10) hex.append("0");
hex.append(Integer.toHexString(b & 0xff));
}
String hexString = hex.toString();
Update as per the comments on the answer of #extraneon, using new BigInteger(byte[]) is also the wrong solution. This doesn't unsign the bytes. Bytes (as all primitive numbers) in Java are signed. They have a negative range. The byte in Java ranges from -128 to 127 while you want to have a range of 0 to 255 to get a proper hexstring. You basically just need to remove the sign to make them unsigned. The & 0xff in the above example does exactly that.
The hexstring as obtained from new BigInteger(bytes).toString(16) is NOT compatible with the result of all other hexstring producing MD5 generators the world is aware of. They will differ whenever you've a negative byte in the MD5 digest.
You have actually successfully digested the message. You just don't know how to present the found digest value properly. What you have is a byte array. That's a bit difficult to read, and a toString of a byte array yields [B#somewhere which is not useful at all.
The BigInteger comes into it as a tool to format the byte array to a single number.
What you do is:
construct a BigInteger with the proper value (in this case that value happens to be encoded in the form of a byte array - your digest
Instruct the BigInteger object to return a String representation (e.g. plain, readable text) of that number, base 16 (e.g. hex)
And the while loop prefixes that value with 0-characters to get a width of 32. I'd probably use String.format for that, but whatever floats your boat :)
MessageDigests compute a byte array of something, the string that you usually see (such as 1f3870be274f6c49b3e31a0c6728957f) is actually just a conversion of the byte array to a hexadecimal string.
When you call MessageDigest.toString(), it calls MessageDigest.digest().toString(), and in Java, the toString method for a byte[] (returned by MessageDigest.digest()) returns a sort of reference to the bytes, not the actual bytes.
In the code you posted, the byte array is changed to an integer (in this case a BigInteger because it would be extremely large), and then converted to hexadecimal to be printed to a String.
The byte array computed by the digest represents a number (a 128-bit number according to http://en.wikipedia.org/wiki/MD5), and that number can be converted to any other base, so the result of the MD5 could be represented as a base-10 number, a base-2 number (as in a byte array), or, most commonly, a base-16 number.
It is OK to google for answers as long as you (eventually) understand what you copy-pasted into your app :-)
In general, I recommend starting with a good Java introductory book, or web tutorial. See these threads for more tips:
https://stackoverflow.com/questions/77839/what-are-the-best-resources-for-learning-java-books-websites-etc
Learning Java
https://stackoverflow.com/questions/78293/good-book-to-learn-to-program-well-in-java-engineering-or-architecture-wise-not
Though I'm afraid that I have no experience whatsoever using Java to play with MD5 hashes, I can recommend Sun's Java Tutorials as a fantastic resource for learning Java. They go through most of the language, and helped me out a ton when I was learing Java.
Also look around for other posts asking the same thing and see what suggestions popped up there.
The reason BigInteger is used is because the byte array is very long, too big too fit into an int or long. However, if you do want to see everything in the byte array, there's an alternate approach. You could just replace the line:
String output = newBA.toString();
with:
String output = Arrays.toString(newBA);
This will print out the contents of the array, not the reference address.
Use an IDE that shows you where the "toString()" method is coming from. In most cases it's just from the Object class and won't be very useful. It's generally recommended to overwrite the toString-method to provide some clean output, but many classes don't do this.
I'm also a newbie to development. For the current problem, I suggest the Book "Introduction To Cryptography With Java Applets" by David Bishop. It demonstrates what you need and so forth...
Any advice on how I can get better
without having to "cheat" by Googling
how to do something all the time?
By by not starting out with an MD5 hasher! Seriously, work your way up little by little on programs that you can complete without worrying about domain-specific stuff like MD5.
If you're dumping everything into main, you're not programming Java.
In a program of this scale, your main() should do one thing: create an MD5Hasher object and then call some methods on it. You should have a constructor that takes an initial string, a method to "do the work" (update, digest), and a method to print the result.
Get some tutorials and spend time on simple, traditional exercises (a Fibonacci generator, a program to solve some logic puzzle), so you understand the language basics before bothering with the libraries, which is what you are struggling with now. Then you can start doing useful stuff.
I wrongly assumed that the "toString" method on my newBA object would convert it to a readable output, but I was, apparently, wrong. How is a person supposed to know which way to go in Java?
You could replace here Java with the language of your choice that you don't know/haven't mastered yet. Even if you worked 10 years in a specific language, you will still get those "Aha! This is the way it's working!"-effects, though not that often as in the beginning.
The point you need to learn here is that toString() is not returning the representation you want/expect, but any the implementer has chosen. The default implementation of toString() is like this (javadoc):
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
How is a person supposed to know which
way to go in Java? I have a background
in C so this Java thing seems pretty
weird. Any advice on how I can get
better without having to "cheat" by
Googling how to do something all the
time?
Obvious answers are 1- google when you have questions (and it's not considered cheating imo) and 2- read books on the subject matter.
Apart from these two, I would recommend trying to find a mentor for yourself. If you do not have experienced Java developers at work, then try to join a local Java developer user group. You can find more experienced developers there and perhaps pick their brains to get answers to your questions.

Categories