How tosolve StringIndexOutOfBounds Exception? - java

I'm copying my program to convert binary data to hex format and print the data in 16bytes format line by line and I'm getting StringIndexOutOfBounds Exception even after data has been printed for some extent please help me solve this problem.
byte[] buffer = new byte[16];
while((line = bis.read(buffer)) != -1)
{
for(int i = 0; i < line; i++)
{
value = Integer.toHexString(0xFF & buffer[i] | 0x100).substring(1);
sb.append(value);//I think here is the problem
}
if(a == 0)
{
incValue = sb.substring(0, 32);
System.out.println(incValue);
}
else
{
counter = counter + 32;
incValue = sb.substring(counter, counter + 32);
System.out.println(incValue);
}
a++;
Output:
5e9d094ec7a7349725b8300212a5048f
b9ce351dfb869a7db694755981f7fbd3
acad5008e54ebd80b82a9676ebd02a0f
4775a61e52c3129c4aba3af1f28c8ee0
9050718e15a8189321d626399ab2612f
212f89f4f9ff0015d03b625cfb990c8a
1c36dc8c13e636f4e74b6df4af853207
49ea39e78c727df55b6f0d5bc90a54fd
f7aba3f8f258496d0256400474236335
Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 216896

instead of this:
incValue = sb.substring(counter, counter + 32);
you can use this:
if((counter+32)< sb.length())
{
incValue = sb.substring(counter, counter + 32);
}
else
{
incValue = sb.substring(counter) //The String is shorter than counter+32 chars
}

Related

How to Verify Mobile no and email id from Secure QR code of Aadhaar card

Official Document for How to Read QR code data from Secure QR code of UIDAI Aadhaar card: https://uidai.gov.in/images/resource/User_manulal_QR_Code_15032019.pdf
Have used zxing scanner to scan Secure QR code,
And was able to get details of aadhar card with the help of follow project in Github:
https://github.com/dimagi/AadharUID
Some how I figured out how to extract photo and bit_indicator_value from converted byte array with the help of instructions on document
But I am unable to get hashed exact hashed value of email and mobile from Secure QR code of Aadhar card byte array to verify
I am bit confused from this line of above mentioned document in page no 6:
Post getting signature value, check the value of
Email_mobile_present_bit_indicator_value:
if its 3 then first read mobile from index (Byte array length – 1-256) and then email from index (Byte array length – 1- 256- 32) in
reverse order. Each value will be of fix size of 32 byte.
If Email_mobile_present_bit_indicator_value is 1 then only mobile
is present.
If Email_mobile_present_bit_indicator_value is 2 then only email is
present.
If Email_mobile_present_bit_indicator_value is 0 then no mobile or
email present.
Email and Mobile value will available in byte. Convert into Hexadecimal
String.
.
I have also prepared last step in document page no 6 but the users mobile/email hash value and documents mobile/email byte arrays hash value never matches
Code snippet:
public ScanResult(String input) {
rawString = input;
// copied from http://www.java-samples.com/showtutorial.php?tutorialid=152
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document dom;
try {
//Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// Replace </?xml... with <?xml...
if (input.startsWith("</?")) {
input = input.replaceFirst("</\\?", "<?");
}
// Replace <?xml...?"> with <?xml..."?>
input = input.replaceFirst("^<\\?xml ([^>]+)\\?\">", "<?xml $1\"?>");
//parse using builder to get DOM representation of the XML file
dom = db.parse(new ByteArrayInputStream(input.getBytes("UTF-8")));
} catch (ParserConfigurationException | SAXException | IOException e) {
dom = null;
}
if (rawString.matches("[0-9]*")) {
type = QR_CODE_TYPE_SECURE;
byte[] msgInBytes = null;
try {
msgInBytes = decompressByteArray(new BigInteger(rawString).toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
if (msgInBytes != null) {
int[] delimiters = locateDelimiters(msgInBytes);
String referenceId = getValueInRange(msgInBytes, delimiters[0] + 1, delimiters[1]);
uid = referenceId.substring(0, 4);
name = getValueInRange(msgInBytes, delimiters[1] + 1, delimiters[2]);
dob = formatDate(getValueInRange(msgInBytes, delimiters[2] + 1, delimiters[3]),
new String[] {"dd-MM-yyyy", "dd/MM/yyyy"});
yob = dob.substring(0, 4);
gender = getValueInRange(msgInBytes, delimiters[3] + 1, delimiters[4]);
co = getValueInRange(msgInBytes, delimiters[4] + 1, delimiters[5]);
dist = getValueInRange(msgInBytes, delimiters[5] + 1, delimiters[6]);
lm = getValueInRange(msgInBytes, delimiters[6] + 1, delimiters[7]);
house = getValueInRange(msgInBytes, delimiters[7] + 1, delimiters[8]);
loc = getValueInRange(msgInBytes, delimiters[8] + 1, delimiters[9]);
pc = getValueInRange(msgInBytes, delimiters[9] + 1, delimiters[10]);
po = getValueInRange(msgInBytes, delimiters[10] + 1, delimiters[11]);
state = getValueInRange(msgInBytes, delimiters[11] + 1, delimiters[12]);
street = getValueInRange(msgInBytes, delimiters[12] + 1, delimiters[13]);
subdist = getValueInRange(msgInBytes, delimiters[13] + 1, delimiters[14]);
vtc = getValueInRange(msgInBytes, delimiters[14] + 1, delimiters[15]);
statusCode = STATUS_SUCCESS;
} else {
statusCode = STATUS_PARSE_ERROR;
uid = "";
name = "";
gender = "";
yob = "";
co = "";
house = "";
street = "";
lm = "";
loc = "";
vtc = "";
po = "";
dist = "";
subdist = "";
state = "";
pc = "";
dob = "";
}
} else {
type = QR_CODE_TYPE_UNKNOWN;
statusCode = STATUS_PARSE_ERROR;
uid = "";
name = "";
gender = "";
yob = "";
co = "";
house = "";
street = "";
lm = "";
loc = "";
vtc = "";
po = "";
dist = "";
subdist = "";
state = "";
pc = "";
dob = "";
}
dobGuess = getDobGuess(dob, yob);
statusText = getStatusText(statusCode);
}
private static int[] locateDelimiters(byte[] msgInBytes) {
int[] delimiters = new int[NUMBER_OF_PARAMS_IN_SECURE_QR_CODE + 1];
int index = 0;
int delimiterIndex;
for (int i = 0; i <= NUMBER_OF_PARAMS_IN_SECURE_QR_CODE; i++) {
delimiterIndex = getNextDelimiterIndex(msgInBytes, index);
delimiters[i] = delimiterIndex;
index = delimiterIndex + 1;
}
return delimiters;
}
private static String getValueInRange(byte[] msgInBytes, int start, int end) {
return new String(Arrays.copyOfRange(msgInBytes, start, end), Charset.forName("ISO-8859-1"));
}
private static int getNextDelimiterIndex(byte[] msgInBytes, int index) {
int i = index;
for (; i < msgInBytes.length; i++) {
if (msgInBytes[i] == -1) {
break;
}
}
return i;
}
private static byte[] decompressByteArray(byte[] bytes) throws IOException {
java.io.ByteArrayInputStream bytein = new ByteArrayInputStream(bytes);
java.util.zip.GZIPInputStream gzin = new GZIPInputStream(bytein);
java.io.ByteArrayOutputStream byteout = new ByteArrayOutputStream();
int res = 0;
byte buf[] = new byte[1024];
while (res >= 0) {
res = gzin.read(buf, 0, buf.length);
if (res > 0) {
byteout.write(buf, 0, res);
}
}
return byteout.toByteArray();
}
private String formatDate(String rawDateString, String[] possibleFormats) {
if (rawDateString.equals("")) {
return "";
}
SimpleDateFormat toFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
ParseException parseException = null;
for (String fromFormatPattern : possibleFormats) {
try {
SimpleDateFormat fromFormat = new SimpleDateFormat(fromFormatPattern);
date = fromFormat.parse(rawDateString);
break;
} catch (ParseException e) {
parseException = e;
}
}
if (date != null) {
return toFormat.format(date);
} else if (parseException != null) {
System.err.println("Expected dob to be in dd/mm/yyyy or yyyy-mm-dd format, got " + rawDateString);
return rawDateString;
} else {
throw new AssertionError("This code is unreachable");
}
}
#NonNull
protected String formatGender(String gender) throws ParseException {
String lowercaseGender = gender.toLowerCase();
if (lowercaseGender.equals("male") || lowercaseGender.equals("m")) {
return "M";
} else if (lowercaseGender.equals("female") || lowercaseGender.equals("f")) {
return "F";
} else if (lowercaseGender.equals("other") || lowercaseGender.equals("o")) {
return "O";
} else {
throw new ParseException("404 gender not found", 0);
}
}
#NonNull
private String getStatusText(int statusCode) {
switch (statusCode) {
case ScanResult.STATUS_SUCCESS:
return "✓";
default:
return "✗";
}
}
#NonNull
private String getDobGuess(String dob, String yob) {
if (dob.equals("")) {
Integer yearInt;
try {
yearInt = Integer.parseInt(yob);
} catch (NumberFormatException e) {
return "";
}
// June 1 of the year
return Integer.toString(yearInt) + "-06-01";
} else {
return dob;
}
}
Github Code Link
Just now got the solution, fetched exact mobile and email hash value from byte array
first remove last 256 bytes from byte array then,
if only mobile present then take last 32 bytes from byte array for mobile
i.e. (array.length - 32 to array.length)
else if only email present then take last 32 bytes from byte array for email i.e. (array.length - 32 to array.length)
else if both email and mobile present then take last 32 bytes from byte array for mobile, take next last 32 bytes for email
i.e. (mobile = array.length - 32 to array.length and
email = array.length - 64 to array.length - 32)
From the byte array you need to read values from index byte_array_length - 256 - 32 to byte_array_length - 256 to get the mobile hash in bytes(you can easily convert the bytes to hexadecimal string) and similarly for email you need to read from index byte_array_length - 256 - 32 - 32 to byte_array_length - 256 - 32.
I have implemented a library for decoding the same but the implementation is in Python.
The question is a bit old but future readers might find these resources useful.
PyPI: aadhaar-py
Github: https://github.com/vishaltanwar96/aadhaar-py

Extracting seprated code from a textfile and storing it into array for further usage

So i should read ID,UserName,Password from a textfile (They are seprated by "~!~") 1~!~Jhon~!~12345
2~!~Mark~!~12345
3~!~Linda~!~abcde
4~!~Mary~!~qwerty
here is how the text file looks like, my code always prompts false even when my input is (1 Jhon 12345).
public boolean LoginAsAdmin (int myID,String myUserName,String myPassword) throws FileNotFoundException{
File myFile = new File ("D:\\Java\\DATA.txt");
Scanner Writer = new Scanner(myFile);
int j = 0;
while (Writer.hasNext()){
Admin myAdmin1 = new Admin();
String output = Writer.nextLine();
StringTokenizer Data = new StringTokenizer(output,"~!~");
if(
myAdmin1.setID(Integer.parseInt((String) Data.nextToken()))&&
myAdmin1.setUserName((String) Data.nextToken())&&
myAdmin1.setPassword((String) Data.nextToken())){
myAdmin[j] = myAdmin1;
}
j++;
}
for (int i = 0; i < j; i++){
if(myAdmin[i].getID() == myID && myAdmin[i].getUserName().equals(myUserName) && myAdmin[i].getPassword().equals(myPassword)){
return true;
}
}
return false;
}
You do not want to put nextToken with an if statement, as it will fail early if the first test is false - Also I not not sure why your setters are returning boolean values.
Firstly I suggest that you use a BufferedReader to read you lines from a text file - see https://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/ for an example.
Then for each line do
String arr[] = inputStr.split("~!~");
for (int i = 0; i < arr.length; i = i + 3) {
Admin myAdmin1 = new Admin ();
String id = arr[i];
myAdmin1.setId (id);
String name = arr[i + 1];
myAdmin1.setUsername (name);
String passwd = arr[i + 2];
myAdmin1.setPassword (passwd)
myAdmin[i % 3] = myAdmin1;
System.out.printf("%d %s %s%n", Integer.parseInt(id), name, passwd);
}

Jaunt Java getText() returning correct text but with lots of "?"

The title explains all, also, I have tried removing them
(because the text is there, but instead of "aldo" there is "al?do", also it seems to have a random pattern)
with (String).replace("?", ""), but with no success.
I have also used this, with a combination of UTF_8,UTF_16 and ISO-8859, with no success.
byte[] ptext = tempName.getBytes(UTF_8);
String tempName1 = new String(ptext, UTF_16);
An example of what I am getting:
Studded Regular Sweatshirt // Instead of this
S?tudde?d R?eg?ular? Sw?eats?h?irt // I get this
Could it be the website that notices the headless browser and tries to "spoof" its content? How can I overcome this?
It looks very likely that site you scrapping intent mix up the 3f and 64 characters into your result.
so you have to mask your self as a normal browser to scrapping or filter it out by replacing.
text simple
Sca???rfa???ce??? E???mbr???oi�d???ered L�e???athe
after filteration
Scarface Embroidered Leather
//Sca???rfa???ce??? E???mbr???oi�d???ered L�e???athe
//Scarface Embroidered Leathe
String hex="5363613f3f3f7266613f3f3f63653f3f3f20453f3f3f6d62723f3f3f6f69‌​643f3f3f65726564204c‌​653f3f3f61746865";
byte[] bytes= hexStringToBytes(hex);
//the only line you need
String res = new String(bytes,"UTF-8").replaceAll("\\\u003f","").replaceAll('�',"").replaceAll("�","");
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(new String(c));
}
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public String printHexString( byte[] b) {
String a = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
a = a+hex;
}
return a;
}

Reading method in java with starting and ending position gone wrong

So basically, I have an exam question that said "Add your directory to this method" and the follow up questions require that I use this method. My classmates that own macs, alongside with the examiner for some reason managed to get the file working.
public static String GetTextFromFile(int startPosition, int endPosition) {
String gotText = "";
String outText = "";
try {
Scanner fileInp = new Scanner(new File(
"C:/Users/Ted/Desktop/diary.txt"));
while (fileInp.hasNextLine()) {
gotText = gotText + fileInp.nextLine();
gotText = gotText + "\n";
}
// System.out.println(gotText);
for (int i = startPosition; i <= endPosition; i = i + 1) {
outText = outText + gotText.charAt(i - 1);
}
fileInp.close();
return outText;
} catch (IOException e) {
return outText;
}
}
I'm using a windows, why does this not work for me?
This is what an error says with an input of
Starting point 1 and ending point 9
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:658)
at java.lang.String.charAt(String.java:658)
at secretmessages.SecretMessages.GetTextFromFile(SecretMessages.java:78)
at secretmessages.SecretMessages.EveryNthCharacterSteganography(SecretMessages.java:199)
at secretmessages.SecretMessages.main(SecretMessages.java:322)
if you did not get any text from your fiel then gotText will still be "", so change this line
for(int i = startPosition; i <= endPosition; i = i + 1)
to
for(int i = startPosition; i <= endPosition && gotText.length () > 0; i = i + 1)
Also I would rather use String.substring
Also log your exceptions
catch(IOException e)
{
e.printStackTrace ();
return outText;
}
Issue in your code is you not check for empty string and use SrtingBuilder rather than String.check endPosition value.
endPosition value could not be greater than total length of string.
See following code may Resolve your Problem.
StringBuilder sb=new StringBuilder("");
while (fileInp.hasNextLine()) {
sb.append(fileInp.nextLine()).append("\n");
}
String gotText=sb.toString();
// System.out.println(gotText);
for (int i = startPosition; i <= endPosition; i = i + 1) {
outText = outText + gotText.charAt(i - 1);
}
if(!gotText.equals("")){
if(endPosition > gotText.length())
endPosition=gotText.length()-1;
for (int i = startPosition; i <= endPosition; i = i + 1) {
outText = outText + gotText.charAt(i - 1);
}
}
outText = outText + gotText.charAt(i - 1);
I think here if in the beginning i==0 then i-1 will throw the out of bound exception. And do check the endPosition it should not go beyond gotText.length().

How do you convert from the ASCII value to string

I'm stuck with some code here and what I'm trying to do is convert a string into its ASCII value, subtract 30 from it and then convert back to a string.
E.g. Enter - hello
Convert to - 104 101 108 108 111
Subtract - 74 71 78 78 81
display - JGNNQ
Code:
import javax.swing.*;
public class practice {
public static void main (String[] args) {
String enc = "";
String encmsg = "";
String msg = JOptionPane.showInputDialog("Enter your message");
int len = msg.length();
for (int i = 0; i< len ; i++) {
char cur = msg.charAt(i);
int val = (int) cur;
val = val -32;
enc = "" + val;
encmsg = encmsg + enc;
}
JOptionPane.showMessageDialog(null, encmsg);
}
}
Thanks in advance
Couple things:
Change val = val -32; to val = val -30; to get the proper subtraction you want in the original problem statement.
Next, change
enc = "" + val; to enc = (char)val;
so that you can convert the value to a proper character. Before, you were just concatenating it to a string, which won't do any conversion. You also need to declare enc as a char at the top of your file.
The full working code should be as follows:
char enc;
String encmsg = "";
String msg = JOptionPane.showInputDialog("Enter your message");
int len = msg.length();
for (int i = 0; i < len; i++) {
char cur = msg.charAt(i);
int val = (int) cur;
val = val - 30;
enc = (char) val;
encmsg = encmsg + enc;
}
JOptionPane.showMessageDialog(null, encmsg);

Categories