StringIndexOutOfBoundsException while decoding - java

I am using ISO9075 decoder in my application. When I try to decode the following String
ISO9075.decode("mediaasset_-g9mdob83oozsr5n_xadda")
its giving the following exception
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 22
at java.lang.String.charAt(Unknown Source)
at org.alfresco.util.ISO9075.matchesEncodedPattern(ISO9075.java:128)
at org.alfresco.util.ISO9075.decode(ISO9075.java:176)
at Test1.main(Test1.java:9)
What may be the problem. Please guide me.
EDIT
Here is my code
public class Test1 {
public static void main(String args[])
{
String s = "mediaasset_-g9mdob83oozsr5n_xadda";
System.out.println(ISO9075.decode(s));
}
}
Thanks.

I just tested it with code found here and could not get your exception.
public static void main(String args[]) {
String s = "mediaasset_-g9mdob83oozsr5n_xadda";
System.out.println(ISO9075.decode(s)); //prints mediaasset_-g9mdob83oozsr5n_xadda
}
public static class ISO9075 {
//I have removed the parts not used by your main()
private static boolean matchesEncodedPattern(String string, int position) {
return (string.length() > position + 6)
&& (string.charAt(position) == '_') && (string.charAt(position + 1) == 'x')
&& isHexChar(string.charAt(position + 2)) && isHexChar(string.charAt(position + 3))
&& isHexChar(string.charAt(position + 4)) && isHexChar(string.charAt(position + 5))
&& (string.charAt(position + 6) == '_');
}
private static boolean isHexChar(char c) {
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
return true;
default:
return false;
}
}
public static String decode(String toDecode) {
if ((toDecode == null) || (toDecode.length() < 7) || (toDecode.indexOf("_x") < 0)) {
return toDecode;
}
StringBuffer decoded = new StringBuffer();
for (int i = 0, l = toDecode.length(); i < l; i++) {
if (matchesEncodedPattern(toDecode, i)) {
decoded.append(((char) Integer.parseInt(toDecode.substring(i + 2, i + 6), 16)));
i += 6;// then one added for the loop to mkae the length of 7
} else {
decoded.append(toDecode.charAt(i));
}
}
return decoded.toString();
}
}

Related

How to parse json object with u0423 code in Android Studio

I don't know how to parse this.
{
"code": 1000,
"result_msg": "Successful",
"result": "{\"birthDateAsText\":\"1999-12-3100:00:00.0\",\"birthPlace\":\"\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423,\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\",\"civilId\":\"123\",\"firstname\":\"\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\",\"gender\":\"\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\",\"lastname\":\"\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\\u0423\",\"nationality\":\"\\u0423\\u0423\\u0423\\u0423\"}"
}
I tried this
if (resultObject.getInt("code") == 1000) {
JSONParse jsonParse = new JSONParse();
JSONObject object = resultObject.getJSONObject("result");
event.onSuccess(jsonParse.convertJson(object));
}
Actually I don't know how to parse and decode jsonobject. Please help me
Try this:
private static String decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len;) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// Read the xxxx
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + aChar - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar == 't')
aChar = '\t';
else if (aChar == 'r')
aChar = '\r';
else if (aChar == 'n')
aChar = '\n';
else if (aChar == 'f')
aChar = '\f';
outBuffer.append(aChar);
}
} else
outBuffer.append(aChar);
}
return outBuffer.toString();
}
Uses:
JSONObject object = resultObject.getJSONObject("result");
System.out.println("Birthday: "+object.getString("birthPlace"))
Decode your response using UTF-8
try {
resp = new String(Base64.decode(response.getBytes("UTF-8"), Base64.NO_WRAP), "UTF-8");
} catch (UnsupportedEncodingException e) {
// Suppress exception (unlikely to happen in prod)
PbLogger.e("Encoding exception", "");
}

Converting all letters in the phone number to digits

Im trying to replace each letter with a digit using the international standard letter/number mapping. I got my output to run correctly however, how do get the dashes in the phone number to appear automatically in the output? For example, if I enter 1800Flowers it prints out as 18003569377. How do I get it to print out as 1-800-3569377 without using regular expressions?
import java.util.Scanner;
public class PhoneKeypad {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//while loop keeps the program running until the user enters quit
while (true) {
System.out.println("\nEnter a phone number or quit to exit:");
String phoneNumber = input.next();
if (phoneNumber.equalsIgnoreCase("quit")) {
System.out.print("\nProgrammed by me");
return;
}
//checks if the phone number entered is at least 8 digits
if (phoneNumber.length() < 8) {
System.out.println("Invalid Phone Number");
} else {
System.out.println(getNumber(phoneNumber));
}
}
}
//method converts all letters in the phone number to digits
public static String getNumber(String phoneNumber) {
int keypadNum = 0;
for (int i = 0; i < phoneNumber.length(); i++) {
char letter = phoneNumber.charAt(i);
if (Character.isAlphabetic(letter)) {
letter = Character.toUpperCase(letter);
switch (letter) {
case 'A':
case 'B':
case 'C':
keypadNum = 2;
break;
case 'D':
case 'E':
case 'F':
keypadNum = 3;
break;
case 'G':
case 'H':
case 'I':
keypadNum = 4;
break;
case 'J':
case 'K':
case 'L':
keypadNum = 5;
break;
case 'M':
case 'N':
case 'O':
keypadNum = 6;
break;
case 'P':
case 'Q':
case 'R':
case 'S':
keypadNum = 7;
break;
case 'T':
case 'U':
case 'V':
keypadNum = 8;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
keypadNum = 9;
break;
default:
System.out.println("Invalid phone number");
}
phoneNumber = phoneNumber.substring(0, i) + keypadNum + phoneNumber.substring(i + 1);
}
}
return phoneNumber;
}
}
Expected Output:
You could use a regular expression with String.replaceAll. Remove the leading one, group the first three digits, the second three digits and the final group of digits. Something like
public static String formatNumber(String phoneNumber) {
if (phoneNumber.startsWith("1")) {
phoneNumber = phoneNumber.substring(1);
}
return phoneNumber.replaceAll("(\\d{3})(\\d{3})(\\d+)", "1-$1-$2-$3");
}
or
public static String formatNumber(String phoneNumber) {
return phoneNumber.replaceAll("1(\\d{3})(\\d{3})(\\d+)", "1-$1-$2-$3");
}
And then call it like
System.out.println(formatNumber(getNumber(phoneNumber)));
I ran it with 1800flowers and got (as expected)
1-800-356-9377
or without regular expressions like
public static String formatNumber(String phoneNumber) {
if (phoneNumber.startsWith("1")) {
phoneNumber = phoneNumber.substring(1);
}
return "1-".concat(phoneNumber.substring(0, 3)) //
.concat("-").concat(phoneNumber.substring(3, 6)) //
.concat("-").concat(phoneNumber.substring(6));
}
Before calling formatNumber, you can remove the dashes to normalize it with something like
public static String removeDashes(String phoneNumber) {
StringBuilder sb = new StringBuilder();
for (char ch : phoneNumber.toCharArray()) {
if (ch != '-') {
sb.append(ch);
}
}
return sb.toString();
}
Then
System.out.println(formatNumber(removeDashes(getNumber(phoneNumber))));

Hex to decimal conversion from a bufferreader

I am having a lot of trouble getting my code to read a certain file, which has 4 hex codes, using buffer reader and converting it to decimal. I was able to get the bufferreader to read the text file and output it to the compiler but i need the program to store the 4 values and have my method convert hex to decimal. This is what i have so far:
import java.io.BufferedReader;
import static java.lang.System.*;
import java.io.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class HexToDecimal {
public static int hexToDecimal(String hexInput) throws IOException {
int decimal = 0;
int len = hexInput.length();
FileReader in = new FileReader("results.txt");
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
out.printf(line + "\n");
}
in.close();
for (int i = 0; i < len; ++i) {
char c = hexInput.charAt(i);
int cValue;
switch (c) {
case '1':
cValue = 1;
break;
case '2':
cValue = 2;
break;
case '3':
cValue = 3;
break;
case '4':
cValue = 4;
break;
case '5':
cValue = 5;
break;
case '6':
cValue = 6;
break;
case '7':
cValue = 7;
break;
case '8':
cValue = 8;
break;
case '9':
cValue = 9;
break;
case 'A':
cValue = 10;
break;
case 'B':
cValue = 11;
break;
case 'C':
cValue = 12;
break;
case 'D':
cValue = 13;
break;
case 'E':
cValue = 14;
break;
case 'F':
cValue = 15;
break;
default: // unexpected character
throw new IllegalArgumentException("Non-hex character " + c
+ " found at position " + i);
}
decimal = 16 * decimal + cValue;
}
return decimal;
}
public static void main(String[] args) {
}
}
Also i can't use parseInt that's why i'm using case breaks. Which is also giving me trouble when it comes to converting hex to decimal. Any help at all is greatly appreciated.
You could change your code in that way and it will work:
import static java.lang.System.out;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
public class HexToDecimal {
public static BigInteger hexToDecimal(String hexInput) throws IOException {
BigInteger decimal = BigInteger.ZERO;
int len = hexInput.length();
for (int i = len - 1; i >= 0; i--) {
char c = hexInput.charAt(len - i - 1);
BigInteger cValue;
switch (c) {
case '1':
cValue = BigInteger.ONE;
break;
case '2':
cValue = BigInteger.valueOf(2l);
break;
case '3':
cValue = BigInteger.valueOf(3l);
break;
case '4':
cValue = BigInteger.valueOf(4l);
break;
case '5':
cValue = BigInteger.valueOf(5l);
break;
case '6':
cValue = BigInteger.valueOf(6l);
break;
case '7':
cValue = BigInteger.valueOf(7l);
break;
case '8':
cValue = BigInteger.valueOf(8l);
break;
case '9':
cValue = BigInteger.valueOf(9l);
break;
case 'A':
cValue = BigInteger.valueOf(10l);
break;
case 'B':
cValue = BigInteger.valueOf(11l);
break;
case 'C':
cValue = BigInteger.valueOf(12l);
break;
case 'D':
cValue = BigInteger.valueOf(13l);
break;
case 'E':
cValue = BigInteger.valueOf(14l);
break;
case 'F':
cValue = BigInteger.valueOf(15l);
break;
default: // unexpected character
throw new IllegalArgumentException("Non-hex character " + c
+ " found at position " + i);
}
decimal = decimal.add(cValue
.multiply(BigInteger.valueOf(16).pow(i)));
}
return decimal;
}
public static void main(String[] args) throws IOException {
FileReader in = new FileReader("results.txt");
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
String[] hexNums = line.split(" ");
for (String hex : hexNums)
out.printf(hexToDecimal(hex) + "\n");
}
in.close();
}
}
If you have to big numbers then you get a wrong answer with int as type so you have to use BigInteger and then the code looks like above with reading from file and printing to the output stream.
I hope it helps.
As Leonid Glanz said just convert the hex String to decimal with Integer.parseInt(hexString, 16). To store more than one value just use a ArrayList.
Edit: Sry didn't read your Op correctly
Here is a bit of code you can use:
import java.io.BufferedReader;
import static java.lang.System.*;
import java.io.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class HexToDecimal {
public static ArrayList<Integer> hexToDecimal() throws IOException {
FileReader in = new FileReader("results.txt");
BufferedReader br = new BufferedReader(in);
String line;
String ram = "";
ArrayList<String> lines = new ArrayList<>();
ArrayList<Integer> output = new ArrayList<>();
while ((line = br.readLine()) != null) {
lines.add(line);
}
for(String y : lines){
ram = "";
for(char x : y.toCharArray()){
ram += convert(x);
}
output.add(Integer.parseInt(ram));
}
in.close();
return output;
}
public static int convert(char x){
if(x == '1'){
return 1;
}else if(x == '2'){
return 2;
}else if(x == '3'){
return 3;
}else if(x == '4'){
return 4;
}else if(x == '5'){
return 5;
}else if(x == '6'){
return 6;
}else if(x == '7'){
return 7;
}else if(x == '8'){
return 8;
}else if(x == '9'){
return 9;
}else if(x == 'A'){
return 10;
}else if(x == 'B'){
return 11;
}else if(x == 'C'){
return 12;
}else if(x == 'D'){
return 13;
}else if(x == 'E'){
return 14;
}else if(x == 'F'){
return 15;
}else{
return 0;
}
}
public static void main(String[] args) {
try {
System.out.println(hexToDecimal());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Convert Decimal to Hex using Recursive method Java

I need to make a recursive method that converts a decimal into hexadecimal.
I can't use Integer.toHexString.
EDIT:I tried this code but it doesn't work properly
public static String Hexa(String s) {
String result = "";
int n = Integer.parseInt(s);
int remainder = n % 16;
if (n == 0) {
return Integer.toString(0);
} else {
switch (remainder) {
case 10:
result = "A" + result;
break;
case 11:
result = "B" + result;
break;
case 12:
result = "C" + result;
break;
case 13:
result = "D" + result;
break;
case 14:
result = "E" + result;
break;
case 15:
result = "F" + result;
break;
default: result = Integer.toString(n/16) + result; break;
}
System.out.println(result);
return Hexa(Integer.toString(n/16)) + result;
}
}
Edit:
Changed the default case and the if (n == 0) loop return statement and it works beautifully now.
new code:
public static String Hexa(String s) {
String result = "";
int n = Integer.parseInt(s);
int remainder = n % 16;
if (n == 0) {
return "";
} else {
switch (remainder) {
case 10:
result = "A";
break;
case 11:
result = "B";
break;
case 12:
result = "C";
break;
case 13:
result = "D";
break;
case 14:
result = "E";
break;
case 15:
result = "F";
break;
default:
result = remainder + result;
break;
}
return Hexa(Integer.toString(n / 16)) + result;
}
}
The problem is in your default clause:
default: result = Integer.toString(n/16) + result; break;
it should read:
default: result = Integer.toString(remainder) + result; break;
That will make your program return "04D2".
But there are several other corrections you can make:
Stop converting back and forth to String. For example that same line can be just:
default: result = remainder + result; break;
Also, change your parameters time to int. If you do need to receive a String, then make this an auxiliary function and make your main function receive a String.
You don't need that breakat the end of your default
You don't need a switch. Isn't 'F' = 'A' + (15 - 10) ? You can figure out how to make a formula that translates any number in the range [10,15] to its corresponding letter.
Instead of Integer.toString(0) you can use "0" ... but that isn't even necessary, you can use "" to avoid that leading 0 in your output. If your are worried for handling the special case where the whole number is "0" add a special clause.
The code below may help you to solve your problem:
public static String decimalToAnyBase(int num,int base) {
if(num<base) {
return num+"";
}
String result=null;
int rem=num%base;
String str=decimalToAnyBase(num/base, base);
result=str+((rem>=10)? (char)(rem-10+'A')+"":rem);
return result;
}
import java.util.Scanner;
public class Assign01_05
{
static String res;
public static void hex(int num) //125
{
if(num>=0 && num<10)
System.out.print(num);
else if(num>=10 && num<=15)
{
switch(num)
{
case 10:
System.out.print('A');
break;
case 11:
System.out.print('B');
break;
case 12:
System.out.print('C');
break;
case 13:
System.out.print('D');
break;
case 14:
System.out.print('E');
break;
case 15:
System.out.println('F');
break;
}
}
else
{
hex(num/16);
hex(num%16);
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the Demical number :");
int num=sc.nextInt();
hex(num);
}
}
import java.util.Scanner;
public class Assign01_05
{
static String res;
public static void hex(int num) //125
{
if(num>=0 && num<10)
System.out.print(num);
else if(num>=10 && num<=15)
{
switch(num)
{
case 10:
System.out.print('A');
break;
case 11:
System.out.print('B');
break;
case 12:
System.out.print('C');
break;
case 13:
System.out.print('D');
break;
case 14:
System.out.print('E');
break;
case 15:
System.out.println('F');
break;
}
}
else
{
hex(num/16);
hex(num%16);
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the Demical number :");
int num=sc.nextInt();
hex(num);
}
}
import java.util.Scanner;
public class Ques5 {
public static void hex(int n) {
if(n>9&&n<=15) {
System.out.printf("%c",'A'+(n-10));
}
else if(n>=0&&n<=9){
System.out.printf("%d",n);
}
else {
hex(n/16);
hex(n%16);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the decimal number : ");
int i = sc.nextInt();
System.out.println("The hexadecimal number is : ");
hex(i);
sc.close();
}
}
const char hex_string[17] = "0123456789ABCDEF";
void dec_to_hex(long long x){
if(x == 0) return;
dec_to_hex(x/16);
printf("%c",hex_string[x%16]);
}
Same in Java

Get junk instead of string in toString()

I have a small metod. It's get string with eng characters and return rus characters string (transliteration); But it's something wrong with it. I have no idea what. It's returned not string on Russian, but some junk like "[C#4057db80";
public String getRussianSting(String engString) {
char[] engCharString = engString.toLowerCase().toCharArray();
char[] rusCharString = new char[30];
for (int i = 0; i <= engCharString.length - 1; i++) {
if (engCharString[i] == ' ')
continue;
if (i + 1 <= engCharString.length - 1) {
if (engCharString[i] == 'c' && engCharString[i + 1] == 'h') {
rusCharString[i] = 'ч';
i++;
continue;
} else if (engCharString[i] == 's' && engCharString[i + 1] == 'h') {
rusCharString[i] = 'ш';
i++;
continue;
} else if (engCharString[i] == 't' && engCharString[i + 1] == 'z') {
rusCharString[i] = 'ц';
i++;
continue;
} else if (engCharString[i] == 'y' && engCharString[i + 1] == 'i') {
rusCharString[i] = 'ы';
i++;
} else if (engCharString[i] == 'y' && engCharString[i + 1] == 'e') {
rusCharString[i] = 'э';
i++;
continue;
} else if (engCharString[i] == 'y' && engCharString[i + 1] == 'u') {
rusCharString[i] = 'ю';
i++;
continue;
} else if (engCharString[i] == 'y' && engCharString[i + 1] == 'a') {
rusCharString[i] = 'я';
i++;
continue;
}
}
switch (engCharString[i]) {
case 'a':
rusCharString[i] = 'а';
break;
case 'b':
rusCharString[i] = 'б';
break;
case 'v':
rusCharString[i] = 'в';
break;
case 'g':
rusCharString[i] = 'г';
break;
case 'd':
rusCharString[i] = 'д';
break;
case 'e':
rusCharString[i] = 'е';
break;
case 'j':
rusCharString[i] = 'ж';
break;
case 'z':
rusCharString[i] = 'з';
break;
case 'i':
rusCharString[i] = 'и';
break;
case 'k':
rusCharString[i] = 'к';
break;
case 'l':
rusCharString[i] = 'л';
break;
case 'm':
rusCharString[i] = 'м';
break;
case 'n':
rusCharString[i] = 'н';
break;
case 'o':
rusCharString[i] = 'о';
break;
case 'p':
rusCharString[i] = 'п';
break;
case 'r':
rusCharString[i] = 'р';
break;
case 's':
rusCharString[i] = 'с';
break;
case 't':
rusCharString[i] = 'т';
break;
case 'u':
rusCharString[i] = 'у';
break;
case 'f':
rusCharString[i] = 'ф';
break;
case 'h':
rusCharString[i] = 'х';
break;
case '\'':
rusCharString[i] = 'ь';
break;
default:
break;
}
}
return rusCharString.toString();
}
return rusCharString.toString();
will return the String showing the object representation of the array. That is one major reason char[] is used for sensitive data instead of String.
try:
return new String(rusCharString);
The problem is that when you use the toString of an array, it will use the one that it inherits from Object class.
If you want to get a proper toString of an array, use java.util.Arrays.toString(rusCharString). The junk that you see is the hash code of that array.
If you want to print the hash code separately, use rusCharArray.hashCode()

Categories