Replacing character pairs with characters in Java - java

So I have want to turn string with character pairs to a string that turns all of the same character pairs to a single letter. Like if I had String: "32 5A 5A 65 75 5A 67"
To "ABBCDBE" (32=A,5A=B,65=C,75=D,67=E). I have this script:
public static void main(String[] args) {
String viesti;
viesti = "23 44 B0 9A 61 A4 91 12 47 A4 91 96 44 B0 BF E0 32 68 EC 96 BF 32 44 B0 CA 32 35 A4 BF 32 EC A4 61 E4 CA 61 5A 32 70 12 91 32 BC 44 12 32 9A 44 91 32 96 91 E0 32 BA CA 61 BC 32 35 CA 47 47 32 E4 44 B0 CA 32 A1 CA 47 47 44 35 32 EC A4 E8 0A CA 61 E0 32 68 EC CA 32 82 61 44 70 47 CA 52 32 35 96 91 EC 32 91 EC 96 BF 32 E8 96 82 EC CA 61 32 96 BF 32 91 EC A4 91 32 91 EC CA 32 0A CA BC 32 96 BF 32 82 61 CA 91 91 BC 32 47 44 B0 9A E0 32 20 32 35 96 47 47 32 E8 44 52 CA 32 12 82 32 35 96 91 EC 32 A4 32 70 CA 91 91 CA 61 32 CA B0 E8 61 BC 82 91 96 44 B0 32 BF EC CA 52 CA 32 A4 B0 BC 32 BF 44 44 B0 E0 32 03 44 12 61 32 BF 44 47 12 91 96 44 B0 32 96 BF 5E 32 96 9A CA 47 47 E4 E8 A1 9A 61 A1 61 E0";
int pituus;
pituus = viesti.length();
int i;
i=1;
char luku;
char luku2;
char merkki;
String hexa;
String merkki2;
String viesti2;
StringBuilder sb = new StringBuilder();
merkki = 'A';
while(i < pituus){
luku = viesti.charAt(i-1);
luku2 = viesti.charAt(i);
if(luku2!=' ' && merkki!=(char)91){
sb.append(luku);
sb.append(luku2);
hexa = sb.toString();
sb.setLength(0);
merkki2 = Character.toString(merkki);
viesti2 = viesti.replace(hexa,merkki2);
i+=3;
merkki++;
}
else {
i+=2;
}
}
System.out.print(viesti2);
}
}
But it seems that viesti2 is only has the first pair replaced and nothing else. How to workaround this?

These character pairs are hexadecimal numbers, I assume?
// Separate the pairs into array elements
String[] pairs = viesti.split(" ");
Map<Integer, Character> codeMap = new HashMap<Integer, Character>();
char[] result = new char[pairs.length];
char curChar = 'A';
// Iterate over the pairs
for (int i = 0; i < pairs.length; i++)
{
if (curChar > 'Z')
{
throw new IndexOutOfBoundsException("Too many code points");
}
// Parse the pair as an integer
int hex = Integer.parseInt(pairs[i], 16);
// Add character to result set
if (!codeMap.containsKey(hex))
{
codeMap.put(hex, curChar);
}
else curChar-=1;
result[i] = codeMap.get(hex);
// Increment character
curChar++;
}
String viesti2 = new String(result);

Related

JOptionPane and Graphs

I would like to know how to give JOptionPane the ability to scroll through a histogram. I managed to get JOptionPane to display my histogram, the only problem is you can't scroll through it. The window stretches to the bottom of the screen and displays only half of the graph.
Note: This only happens when reading large input files that contain 300+ integers between 0 and 130. The program will not recognize anything else.
Input Values:
54
38
42
40
34
51
54
58
61
55
54
42
40
34
51
54
54
54
38
60
42
40
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
32
28
24
18
9
4
22
31
38
34
41
32
28
24
18
31
38
34
41
32
28
24
18
31
38
34
41
32
28
31
38
35
51
34
41
56
63
59
66
48
46
58
41
56
63
51
59
48
46
58
41
56
63
53
52
58
48
49
58
41
56
63
51
52
59
58
66
63
71
69
70
72
67
66
63
71
74
75
69
73
78
72
67
63
71
74
59
56
69
70
78
72
66
71
74
69
70
78
72
67
63
59
58
57
64
71
72
67
63
59
64
71
73
79
75
78
72
67
63
59
63
71
73
75
78
72
67
63
57
73
77
75
78
72
67
71
73
77
75
78
81
83
87
84
91
92
90
84
76
83
82
89
78
81
83
87
84
91
92
90
84
78
85
82
89
96
91
78
81
83
86
82
91
92
90
84
85
82
89
92
96
91
95
97
98
91
95
97
93
87
85
94
89
92
96
93
96
97
98
98
100
102
95
97
93
87
88
89
93
84
89
92
95
95
95
97
94
91
87
84
80
90
82
80
73
75
70
74
74
75
70
66
63
71
69
70
72
67
66
63
71
55
59
53
58
52
67
63
71
74
59
56
69
70
58
62
56
51
54
49
60
68
62
67
63
59
58
57
64
44
38
42
40
34
51
54
55
54
42
40
34
51
54
54
54
38
42
31
38
34
41
32
28
24
18
31
38
34
41
32
28
24
18
31
38
34
41
32
28
31
28
35
41
34
37
26
23
29
40
45
46
39
31
40
38
29
34
36
import javax.swing.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class CoolWeather
{
static JFileChooser selecter;
static Scanner in;
public static void main(String[] args) throws FileNotFoundException
{
//Get Input File
File inputFile;
selecter = new JFileChooser(".");
int status = selecter.showOpenDialog(null);
if(status != JFileChooser.APPROVE_OPTION)
{
JOptionPane.showMessageDialog(null, "Closing Program");
System.exit(0);
}
inputFile = selecter.getSelectedFile();
JOptionPane.showMessageDialog(null, "Opening: " + inputFile.getName());
//Creates Array
int[] temps = readData(inputFile);
//Prints Histogram
showMessage(temps);
}
//The Following Method Creates and Populates An Array With Data
//From The Input File
public static int[] readData(File inputFile) throws FileNotFoundException
{
in = new Scanner(inputFile);
in.useDelimiter("[^0-9/s]+");
int[] temps = new int[131];
int count = 0;
int num;
do
{
num = in.nextInt();
count++;
temps[num]++;
}
while (in.hasNextInt());
JOptionPane.showMessageDialog(null, "The Number Of Entries Read: " + count);
return temps;
}
public static void showMessage(int[] temps)
{
String output = "Temp\tCount\tVisual";
// for each array element, output a bar in histogram
for ( int counter = 0; counter < temps.length; counter++ )
{
if (temps[counter] > 0)
{
output += "\n" + counter + "\t" + temps[ counter ] + "\t";
// print bar of asterisks
for ( int stars = 0; stars < temps[ counter ]; stars++ )
{output += "*";}
}
} // end outer for
JTextArea outputArea = new JTextArea();
outputArea.setText( output );
JOptionPane.showMessageDialog( null, outputArea, "CoolWeather Histogram", JOptionPane.INFORMATION_MESSAGE );
System.exit( 0 );
}
}
This is the JOptionPane I use for UI when handling exceptions, but the principle is the same - JTextArea in JScrollPane
JLabel label = new JLabel(e.getLocalizedMessage() + ":");
label.setFont(getFont().deriveFont(Font.BOLD));
label.setAlignmentX(JLabel.LEFT_ALIGNMENT);
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
JTextArea textArea = new JTextArea();
textArea.setEditable(false);
textArea.setFont(getFont());
textArea.setTabSize(2);
textArea.setText(writer.toString());
SwingUtilities.invokeLater(() -> textArea.setCaretPosition(0));
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
scrollPane.setPreferredSize(new Dimension(500, 200));
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(label);
panel.add(Box.createVerticalStrut(5));
panel.add(scrollPane);
JOptionPane.showMessageDialog(this, panel, ApplicationInfo.getAppName(), JOptionPane.ERROR_MESSAGE);
JTextArea outputArea = new JTextArea();
outputArea.setText(output);
outputArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(outputArea);
scrollPane.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
scrollPane.setPreferredSize(new Dimension(500, 200));
JOptionPane.showMessageDialog( null, scrollPane, "CoolWeather Histogram", JOptionPane.INFORMATION_MESSAGE);
System.exit( 0 );

Verifying a signed string in JavaCard return `0x6F00` status word

I wrote the below JavaCard program to Sign a 4 byte length data based on ALG_RSA_SHA_256_PKCS1 algorithm and also to verify this signature:
package fileSigner;
import javacard.framework.*;
import javacard.security.KeyPair;
import javacard.security.RSAPrivateKey;
import javacard.security.RSAPublicKey;
import javacard.security.Signature;
public class FileSigning extends Applet {
//Proprietary Status Words
private static final short SIGN_VERIFIED_SW = (short) 0x6701;
private static final short SIGN_NOT_VERIFIED_SW = (short) 0x6702;
//Proprietary Instructions
private static final byte SIGN_INS = (byte) 0x00;
private static final byte VERIFY_INS = (byte) 0x02;
private static final byte RET_PUB_KEY_INS = (byte) 0x04;
//Required Objects
private static RSAPrivateKey privateKey;
private static RSAPublicKey publicKey;
private static KeyPair keyPair;
private static Signature signature;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new FileSigning();
}
protected FileSigning() {
register();
keyPair = new KeyPair(KeyPair.ALG_RSA, (short) 1024);
keyPair.genKeyPair();
publicKey = (RSAPublicKey) keyPair.getPublic();
privateKey = (RSAPrivateKey) keyPair.getPrivate();
signature = Signature.getInstance(Signature.ALG_RSA_SHA_256_PKCS1, false);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case SIGN_INS:
signature.init(privateKey, Signature.MODE_SIGN);
byte[] dataSignature = JCSystem.makeTransientByteArray((short) 128, JCSystem.CLEAR_ON_RESET);
short signLen = signature.sign(buffer, ISO7816.OFFSET_CDATA, (byte) ISO7816.OFFSET_LC, dataSignature, (byte) 0);
Util.arrayCopyNonAtomic(dataSignature, (short) 0, buffer, (short) 0, signLen);
apdu.setOutgoingAndSend((short) 0, signLen);
break;
case VERIFY_INS:
signature.init(privateKey, Signature.MODE_VERIFY);
boolean isVerified = signature.verify(buffer, (short)ISO7816.OFFSET_CDATA, (short)0x80, buffer, (short)(ISO7816.OFFSET_CDATA + 0X80), (short)0X04);
if (isVerified) {
ISOException.throwIt(SIGN_VERIFIED_SW);
} else {
ISOException.throwIt(SIGN_NOT_VERIFIED_SW);
}
break;
case RET_PUB_KEY_INS:
break;
default:
ISOException.throwIt((short) ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
Well, It seems that it works fine for sign method.
For example in the follow I sign 11223344:
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 000000000411223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00 04 11 22 33 44
Received (SW1=0x90, SW2=0x00):
7B EE DE 3E 16 D6 82 CF 67 53 CC AF 87 F3 4F 31 {..>....gS....O1
BB A6 66 B6 4E E3 F5 FD 0E 04 18 24 63 C1 98 D4 ..f.N......$c...
17 CC 56 DA A0 5F 78 4D A5 AE DF E4 A6 E0 35 B6 ..V.._xM......5.
F0 F3 59 45 1E 89 EE 02 69 15 8C 27 7B 10 94 02 ..YE....i..'{...
F1 C5 A4 1C F2 3C 1A 75 8A FC 89 4F 59 A4 D5 A0 .....<.u...OY...
84 C5 5E 70 F8 B7 80 10 3D D3 84 56 EC CB 1D 01 ..^p....=..V....
D2 F4 F0 F4 FD 91 5A 52 45 17 A7 08 9D 26 82 A7 ......ZRE....&..
E3 67 A6 2C D8 CC 7F 59 F1 98 4A 4F 5D 78 63 DD .g.,...Y..JO]xc.
But I have problems with the verify method!
In the below I tried to verify the above signature:
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 00020000847BEEDE3E16D682CF6
753CCAF87F34F31BBA666B64EE3F5FD0E04182463C198D417CC56DAA05F784DA5AEDFE4A6E035B6F
0F359451E89EE0269158C277B109402F1C5A41CF23C1A758AFC894F59A4D5A084C55E70F8B780103
DD38456ECCB1D01D2F4F0F4FD915A524517A7089D2682A7E367A62CD8CC7F59F1984A4F5D7863DD1
1223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 02 00 00 84 7B EE DE 3E 16 D6 82 CF 67 53 CC AF 87 F3 4F 31 BB A6 66
B6 4E E3 F5 FD 0E 04 18 24 63 C1 98 D4 17 CC 56 DA A0 5F 78 4D A5 AE DF E4 A6 E
0 35 B6 F0 F3 59 45 1E 89 EE 02 69 15 8C 27 7B 10 94 02 F1 C5 A4 1C F2 3C 1A 75
8A FC 89 4F 59 A4 D5 A0 84 C5 5E 70 F8 B7 80 10 3D D3 84 56 EC CB 1D 01 D2 F4 F0
F4 FD 91 5A 52 45 17 A7 08 9D 26 82 A7 E3 67 A6 2C D8 CC 7F 59 F1 98 4A 4F 5D 7
8 63 DD 11 22 33 44
Received (SW1=0x6F, SW2=0x00)
Update1:
I was wrongly wrote
signature.init(privateKey, Signature.MODE_VERIFY);
instead of
signature.init(publicKey, Signature.MODE_VERIFY);
in the section of VERIFY_INS. So I correct it and now the output is as below:
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 000000000411223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00 04 11 22 33 44
Received (SW1=0x90, SW2=0x00):
73 87 1C 58 07 EB F5 55 42 E3 37 FC 84 3A CA 91 s..X...UB.7..:..
FB F4 4D AD 70 FC 43 84 C0 26 DC AE 03 47 28 F3 ..M.p.C..&...G(.
F6 77 6B 53 93 96 92 4B 66 C8 BA 05 0F 65 56 CE .wkS...Kf....eV.
0E 7A 56 DE 5A 9C FF 4C FB B5 82 33 81 22 BD BE .zV.Z..L...3."..
76 99 15 87 5D 9C 4C 5F 6A 75 38 99 A9 28 D6 45 v...].L_ju8..(.E
A5 F4 8C A2 AE 89 28 49 ED 72 14 FD 7E 3C 6A F4 ......(I.r..~<j.
EA C2 7C BD AB D3 B3 91 1C 24 E0 29 B4 9C 07 82 ..|......$.)....
32 B1 BF 00 A5 A0 82 48 C2 01 82 A1 90 5A 47 05 2......H.....ZG.
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 000200008473871C5807EBF5554
2E337FC843ACA91FBF44DAD70FC4384C026DCAE034728F3F6776B539396924B66C8BA050F6556CE0
E7A56DE5A9CFF4CFBB582338122BDBE769915875D9C4C5F6A753899A928D645A5F48CA2AE892849E
D7214FD7E3C6AF4EAC27CBDABD3B3911C24E029B49C078232B1BF00A5A08248C20182A1905A47051
1223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 02 00 00 84 73 87 1C 58 07 EB F5 55 42 E3 37 FC 84 3A CA 91 FB F4 4D
AD 70 FC 43 84 C0 26 DC AE 03 47 28 F3 F6 77 6B 53 93 96 92 4B 66 C8 BA 05 0F 6
5 56 CE 0E 7A 56 DE 5A 9C FF 4C FB B5 82 33 81 22 BD BE 76 99 15 87 5D 9C 4C 5F
6A 75 38 99 A9 28 D6 45 A5 F4 8C A2 AE 89 28 49 ED 72 14 FD 7E 3C 6A F4 EA C2 7C
BD AB D3 B3 91 1C 24 E0 29 B4 9C 07 82 32 B1 BF 00 A5 A0 82 48 C2 01 82 A1 90 5
A 47 05 11 22 33 44
Received (SW1=0x67, SW2=0x02)
As you see above, the card couldn't verify the signature that it create itself.
Updata2:
Based on dear Mr Maarten's answer I added setIncomingAndReceive() method to my program as below:
public class FileSigning extends Applet {
//Proprietary Status Words
private static final short SIGN_VERIFIED_SW = (short) 0x6701;
private static final short SIGN_NOT_VERIFIED_SW = (short) 0x6702;
//Proprietary Instructions
private static final byte SIGN_INS = (byte) 0x00;
private static final byte VERIFY_INS = (byte) 0x02;
private static final byte RET_PUB_KEY_INS = (byte) 0x04;
//Required Objects
private static RSAPrivateKey privateKey;
private static RSAPublicKey publicKey;
private static KeyPair keyPair;
private static Signature signature;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new FileSigning();
}
protected FileSigning() {
register();
keyPair = new KeyPair(KeyPair.ALG_RSA, (short) 1024);
keyPair.genKeyPair();
publicKey = (RSAPublicKey) keyPair.getPublic();
privateKey = (RSAPrivateKey) keyPair.getPrivate();
signature = Signature.getInstance(Signature.ALG_RSA_SHA_256_PKCS1, false);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
byte[] incomingData = JCSystem.makeTransientByteArray((short) 256, JCSystem.CLEAR_ON_RESET);
short bytesLeft;
short readCount;
short offSet = 0x00;
switch (buffer[ISO7816.OFFSET_INS]) {
case SIGN_INS:
signature.init(privateKey, Signature.MODE_SIGN);
bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
readCount = apdu.setIncomingAndReceive();
while (bytesLeft > 0) {
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, incomingData, offSet, readCount);
bytesLeft -= readCount;
offSet += readCount;
readCount = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
}
short signLen = signature.sign(buffer, ISO7816.OFFSET_CDATA, (byte) ISO7816.OFFSET_LC, incomingData, (byte) 0);
Util.arrayCopyNonAtomic(incomingData, (short) 0, buffer, (short) 0, signLen);
apdu.setOutgoingAndSend((short) 0, signLen);
break;
case VERIFY_INS:
signature.init(publicKey, Signature.MODE_VERIFY);
bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
readCount = apdu.setIncomingAndReceive();
while (bytesLeft > 0) {
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, incomingData, offSet, readCount);
bytesLeft -= readCount;
offSet += readCount;
readCount = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
}
boolean isVerified = signature.verify(incomingData, (short) 0, (short) 0x80, incomingData, (short) 0X80, (short) 0X04);
if (isVerified) {
ISOException.throwIt(SIGN_VERIFIED_SW);
} else {
ISOException.throwIt(SIGN_NOT_VERIFIED_SW);
}
break;
case RET_PUB_KEY_INS:
break;
default:
ISOException.throwIt((short) ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
Well, it seems that there is something wrong still:
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 000000000411223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00 04 11 22 33 44
Received (SW1=0x90, SW2=0x00):
75 08 A1 D0 D7 C6 9E 60 3E 78 F0 3A 6B 50 A0 D8 u......`>x.:kP..
80 2E F3 3E 29 2C 0E 13 15 DC 78 74 14 33 4D 36 ...>),....xt.3M6
7E 5E C5 65 67 92 A0 7E B4 0A A1 C0 DE F2 63 44 ~^.eg..~......cD
84 E3 20 CC 48 96 6E B2 28 9A 1B 07 53 ED 70 AF .. .H.n.(...S.p.
8E 01 24 E0 B9 80 89 98 ED B7 A0 BB 81 37 81 22 ..$..........7."
1C C8 54 A4 91 D0 8D 83 12 31 41 1A 56 76 23 D4 ..T......1A.Vv#.
09 5C BD 1E 75 A6 D8 3A 57 15 D8 5E B0 B9 B5 E7 .\..u..:W..^....
32 46 BE C5 A8 58 79 1B D4 C5 20 DD 48 D3 70 CB 2F...Xy... .H.p.
C:\OpenSCTool:> OSC.exe -s 00a4040006010203040501 -s 00020000847508A1D0D7C69E603
E78F03A6B50A0D8802EF33E292C0E1315DC787414334D367E5EC5656792A07EB40AA1C0DEF263448
4E320CC48966EB2289A1B0753ED70AF8E0124E0B9808998EDB7A0BB813781221CC854A491D08D831
231411A567623D4095CBD1E75A6D83A5715D85EB0B9B5E73246BEC5A858791BD4C520DD48D370CB1
1223344
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 02 00 00 84 75 08 A1 D0 D7 C6 9E 60 3E 78 F0 3A 6B 50 A0 D8 80 2E F3
3E 29 2C 0E 13 15 DC 78 74 14 33 4D 36 7E 5E C5 65 67 92 A0 7E B4 0A A1 C0 DE F
2 63 44 84 E3 20 CC 48 96 6E B2 28 9A 1B 07 53 ED 70 AF 8E 01 24 E0 B9 80 89 98
ED B7 A0 BB 81 37 81 22 1C C8 54 A4 91 D0 8D 83 12 31 41 1A 56 76 23 D4 09 5C BD
1E 75 A6 D8 3A 57 15 D8 5E B0 B9 B5 E7 32 46 BE C5 A8 58 79 1B D4 C5 20 DD 48 D
3 70 CB 11 22 33 44
Received (SW1=0x67, SW2=0x02)
Your verify() arguments are probably swapped (given you have [128 bytes signature][4 bytes data] in the incomingData):
boolean isVerified = signature.verify(incomingData, (short)0x80, (short) 4, incomingData, (short)0, (short)0x80);
Your java card code needs some polishing, for example the dataSignature/incomingData buffers should be allocated only once in the constructor (and CLEAR_ON_DESELECT should suffice).
You are forgetting to call apdu.setIncomingAndSend(), so all data may not be in the buffer. For small data (4 bytes) it usually is, but for larger data (i.e. the one that includes the signature for verification, it isn't.

JNI - SetByteArrayRegion does not work

I had some problems about encoding/decoding audio in my wrapper code, I debugged my code and finally found out that SetByteArrayRegion does not work as expected. Here we go:
// incoming parameters => jbyteArray jencoded
jbyte encoded[320]; //
... // fill encoded with 'encodedSize' number of bytes
int i;
for (i = 0; i < encodedSize; i++) {
fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->SetByteArrayRegion(env, jencoded, 0, encodedSize, encoded);
jbyte* encoded_test = (*env)->GetByteArrayElements(env, jencoded, NULL);
for (i = 0; i < encodedSize; i++) {
fprintf(encodeDbg, "%02X ", (unsigned char)(encoded_test[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->ReleaseByteArrayElements(env, jencoded, encoded_test, JNI_ABORT);
The values in encoded and jencoded (i.e. encoded_test) do not match! After calling this procedure multiple times, the content of encodeDbg file is as follows:
08 40 64 6A 6A 00 00 00 61 16 0D 2B 2D 7C F1 EF 8B D0 AE D3 21 39
D0 F4 40 1B 00 00 00 00 16 00 00 00 00 F3 40 1B 8B D0 AE D3 21 39
08 40 64 6A 6A 00 00 00 74 DB F7 02 23 18 01 86 8E 6D 4A 56 9E 9C 64 41 43 E8 09
D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 8E 6D 4A 56 9E 9C 64 41 43 E8 09
08 40 64 6A 6A 00 00 00 D5 A4 A3 5E A3 DC B1 3B 2D 3D 6C 4C A4
D0 F4 40 1B 00 00 00 00 15 00 00 00 00 F3 40 1B 2D 3D 6C 4C A4
08 40 64 6A 6A 00 00 00 AC 59 7A 0E 3D A1 50 43 57 20 58 41 5F 5C 74 88 22 1B 5D
D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 57 20 58 41 5F 5C 74 88 22 1B 5D
08 40 64 6A 6A 00 00 00 73 33 13 51 56 77 BF 41 93 0A 61 9C 57 30 A3 DB B9 80
D0 F4 40 1B 00 00 00 00 1A 00 00 00 00 F3 40 1B 93 0A 61 9C 57 30 A3 DB B9 80
08 40 64 6A 6A 00 00 00 9C 05 BB 57 32 9B 14 2B 9E A1 87 DF EF 55 7F 4E B5 FD C2
D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 9E A1 87 DF EF 55 7F 4E B5 FD C2
08 40 64 6A 6A 00 00 00 03 4C 7F ED 08 28 18 5D E1 23 D9 7C DD E8 27 BC 46 12 FA 0D 0E 56 29 C2 14 58
D0 F4 40 1B 00 00 00 00 22 00 00 00 00 F3 40 1B E1 23 D9 7C DD E8 27 BC 46 12 FA 0D 0E 56 29 C2 14 58
08 40 64 6A 6A 00 00 00 77 09 3F 7E 57 78 53 64 E2 39 74 6B E1 E5 AB 2C EB C4 D7 FE 80
D0 F4 40 1B 00 00 00 00 1D 00 00 00 00 F3 40 1B E2 39 74 6B E1 E5 AB 2C EB C4 D7 FE 80
There is a problem with the first 16 bytes, while the rest is of the array is ok. Any suggestion is highly appreciated.
EDIT:
I compile the JNI part (C stuff) on linux (with mingw), and copy the dll to Windows, where I run the Java application. May this cross platform operations cause the problem? Do I need to add some extra flag/parameter to the compiler or linker?
SECOND EDIT:
I slightly changed the code to see the contents of encoded after SetByteArrayRegion call. The code and the output is as following:
// incoming parameters => jbyteArray jencoded
jbyte encoded[320]; //
... // fill encoded with 'encodedSize' number of bytes
int i;
for (i = 0; i < encodedSize; i++) {
fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->SetByteArrayRegion(env, jencoded, 0, encodedSize, encoded);
jbyte* encoded_test = (*env)->GetByteArrayElements(env, jencoded, NULL);
for (i = 0; i < encodedSize; i++) {
fprintf(encodeDbg, "%02X ", (unsigned char)(encoded_test[i]));
}
fprintf(encodeDbg, "\n");
for (i = 0; i < encodedSize; i++) {
fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n\n");
fflush(encodeDbg);
(*env)->ReleaseByteArrayElements(env, jencoded, encoded_test, JNI_ABORT);
Sample output:
08 40 64 6A 6A 00 00 00 61 16 0D 2B 2D 7C F1 EF 8B D0 AE D3 21 39
20 F1 07 1B 00 00 00 00 16 00 00 00 50 EF 07 1B 8B D0 AE D3 21 39
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C
08 40 64 6A 6A 00 00 00 74 DB F7 02 23 18 01 86 8E 6D 4A 56 9E 9C 64 41 43 E8 09
20 F1 07 1B 00 00 00 00 1B 00 00 00 50 EF 07 1B 8E 6D 4A 56 9E 9C 64 41 43 E8 09
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64
08 40 64 6A 6A 00 00 00 D5 A4 A3 5E A3 DC B1 3B 2D 3D 6C 4C A4
20 F1 07 1B 00 00 00 00 15 00 00 00 50 EF 07 1B 2D 3D 6C 4C A4
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6
08 40 64 6A 6A 00 00 00 AC 59 7A 0E 3D A1 50 43 57 20 58 41 5F 5C 74 88 22 1B 5D
20 F1 07 1B 00 00 00 00 1B 00 00 00 50 EF 07 1B 57 20 58 41 5F 5C 74 88 22 1B 5D
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64
08 40 64 6A 6A 00 00 00 73 33 13 51 56 77 BF 41 93 0A 61 9C 57 30 A3 DB B9 80
20 F1 07 1B 00 00 00 00 1A 00 00 00 50 EF 07 1B 93 0A 61 9C 57 30 A3 DB B9 80
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18
08 40 64 6A 6A 00 00 00 4B 2D C9 D8 69 E5 B9 BE 2F 77 13 0F 89 E6 A3 52 89 8E 96 CC
20 F1 07 1B 00 00 00 00 1C 00 00 00 50 EF 07 1B 2F 77 13 0F 89 E6 A3 52 89 8E 96 CC
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64 6A

How to convert HexString To jpg image in java?

Hi I have a hex String I need to convert that into jpg image please explain me how to do that i have done like this.This Hex String I need to convert into the jpg image,I am trying here but its not coming.
String hex="ff d8 ff e0 00 11 4a 46 49 46 00 01 01 01 00 00 00 00 00 00 0a ff db 00 43 00 08 06 06 07 06 05 08 07 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 0f 14 1d 1a 1f 1e 1d 1a 1c 1c 20 24 2e 27 20 22 2c 23 1c 1c 28 37 29 2c 30 31 34 34 34 1f 27 39 3d 38 32 3c 2e 33 34 32 ff db 00 43 01 09 09 09 0c 0b 0c 18 0d 0d 18 32 21 1c 21 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 42 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a 83 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 f2 f3 f4 f5 f6 f7 f8 f9 fa ff c4 00 1f 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 a1 b1 c1 09 23 33 52 f0 15 62 72 d1 0a 16 24 34 e1 25 f1 17 18 19 1a 26 27 28 29 2a35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65";
// String sb = "0d 02 01 02 4e 52 30 39 47 30 35 36 31 38 00 03 00 fa 01 95 e4 53 c0 a8 51 b1 53 a3 03 40 89 54 66 9c ee 10 01 de 9a 5c 22 e6 a0 2c 5d b2 69 8c 9d 79 e6 a5 41 50 c6 78 ab 31 8c 8a 00 72 83 53 2a e0 67 14 d0 2a 54 1b 85 00 00 76 a6 b4 64 1e 95 32 a1 c8 a5 90 f3 81 da 98 15 88 c7 51 54 6e 63 cb 1e 3a d6 99 19 19 ef 55 6e 13 2b 91 49 89 98 2f a7 49 b8 95 20 8a 88 d9 cc b9 f9 0d 6d 85 e6 9e 23 e3 a5 06 7c a6 02 c6 e8 c3 2a 72 0d 74 90 1d d1 29 f5 14 cf 29 5b 82 01 fa 8a 9d 14 00 00 e0 50 38 ad 46 4c 38 15 89 7a b8 9c fa 11 5b f2 2e 56 a9 5c e9 ad 39 0e 18 03 8e f4 8a 68 c4 14 d2 39 ad 07 d2 ae 17 a0 0d f4 35 5d ed 27 4f bd 1b 0f c2 99 9d 88 06 41 ae 9f 4e 19 b2 88 fb 57 36 54 83 c8 23 eb c5 74 da 70 c5 94 7f 4a 07 1d cb 2c 3e 53 58 77 1c ca 45 6e 37 dd 35 89 38 fd e9 a1 97 2d 88 76 d1 8a 76 29 c8 bb 98 52 32 23 da 4f 6a 96 38 01 19 6e 95 21 c0 e0 0a 98 0d d1 0c 75 14 0a c4 b6 d1 a0 8f 81 8c d3 9d 76 1a 92 24 21 00 a8 e7 38 fc 29 9b c7 62 85 c9 dc f8 f4 aa f8 a7 bb 65 89 a6 1e b4 8c a5 ab 0a 43 41 a6 f7 a0 43 5e 95 54 e0 50 06 48 06 a4 c7 14 0e 28 85 86 2a 32 78 a9 5e a0 90 e0 52 35 7b 12 e2 81 4b 8e 69 71 4c 60 bd 6a 74 a8 50 73 53 31 c0 da 3a d0 00 cd b8 e0 74 14 a0 8c e3 bd 20 18 1c 75 a6 a9 cb 8d c3 9c d3 02 c4 7c 1a b8 83 8a aa 8a 59 b8 ab 89 c0 02 80 1e 38 a5 52 41 e2 90 0a 51 40 0f f3 1b 34 ed e1 ba f5 a8 a9 71 40 12 16 e3 02 a2 75 ca 9a 78 a5 c1 34 01 45 46 3a d4 8b 43 ae d9 0f bd 0b 40 89 00 14 f0 05 31 4d 48 a2 81 8e db 9a 70 5a 45 19 a9 00 a6 16 1a 12 83 1e 6a 40 29 c1 68 15 91 58 db 46 df 79 14 fe 15 24 71 88 d7 6a 8c 01 da a6 c5 21 5a 01 22 0d 0a 2a 4b 57 00 0f 00 01 82 03 00 00 0d 0a ";
// String raw_DeviceId = sb.substring(38, 1040);
byte[] b = HexStringToByteArray(hex);
// imageInFile.read(b);
for (int i = 0; i < b.length; i++) {
byte c = b[i];
System.out.println("c = " + c);
}
/*
* Converting Image byte array into Base64 String
*/
String imageDataString = encodeImage(b);
/*
* Converting a Base64 String into Image byte array
*/
byte[] imageByteArray = decodeImage(imageDataString);
/*
* Write a image byte array into file system
*/
FileOutputStream imageOutFile = new FileOutputStream("D:/img6.jpg");
imageOutFile.write(imageByteArray);
imageInFile.close();
imageOutFile.close();
System.out.println("Image Successfully Manipulated!");
} catch (FileNotFoundException e) {
System.out.println("Image not found" + e);
} catch (IOException ioe) {
System.out.println("Exception while reading the Image " + ioe);
}
}
/**
* Encodes the byte array into base64 string
*
* #param imageByteArray - byte array
* #return String a {#link java.lang.String}
*/
public static String encodeImage(byte[] imageByteArray) {
return Base64.encodeBase64URLSafeString(imageByteArray);
}
/**
* Decodes the base64 string into byte array
*
* #param imageDataString - a {#link java.lang.String}
* #return byte array
*/
public static byte[] decodeImage(String imageDataString) {
return Base64.decodeBase64(imageDataString);
}
}
And HexString to bytearray convertion:
public static byte[] HexStringToByteArray(String hexStr) {
int len = hexStr.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4)
+ Character.digit(hexStr.charAt(i + 1), 16));
}
return data;
}
Update:
String hex = "ff d8 ff e0 00 11 4a 46 49 46 00 01 01 01 00 00 00 00 00 00 0a ff db 00 43 00 08 06 06 07 06 05 08 07 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 0f 14 1d 1a 1f 1e 1d 1a 1c 1c 20 24 2e 27 20 22 2c 23 1c 1c 28 37 29 2c 30 31 34 34 34 1f 27 39 3d 38 32 3c 2e 33 34 32 ff db 00 43 01 09 09 09 0c 0b 0c 18 0d 0d 18 32 21 1c 21 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 42 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a 83 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 f2 f3 f4 f5 f6 f7 f8 f9 fa ff c4 00 1f 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 a1 b1 c1 09 23 33 52 f0 15 62 72 d1 0a 16 24 34 e1 25 f1 17 18 19 1a 26 27 28 29 2a35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65";
// String sb = "0d 02 01 02 4e 52 30 39 47 30 35 36 31 38 00 03 00 fa 01 95 e4 53 c0 a8 51 b1 53 a3 03 40 89 54 66 9c ee 10 01 de 9a 5c 22 e6 a0 2c 5d b2 69 8c 9d 79 e6 a5 41 50 c6 78 ab 31 8c 8a 00 72 83 53 2a e0 67 14 d0 2a 54 1b 85 00 00 76 a6 b4 64 1e 95 32 a1 c8 a5 90 f3 81 da 98 15 88 c7 51 54 6e 63 cb 1e 3a d6 99 19 19 ef 55 6e 13 2b 91 49 89 98 2f a7 49 b8 95 20 8a 88 d9 cc b9 f9 0d 6d 85 e6 9e 23 e3 a5 06 7c a6 02 c6 e8 c3 2a 72 0d 74 90 1d d1 29 f5 14 cf 29 5b 82 01 fa 8a 9d 14 00 00 e0 50 38 ad 46 4c 38 15 89 7a b8 9c fa 11 5b f2 2e 56 a9 5c e9 ad 39 0e 18 03 8e f4 8a 68 c4 14 d2 39 ad 07 d2 ae 17 a0 0d f4 35 5d ed 27 4f bd 1b 0f c2 99 9d 88 06 41 ae 9f 4e 19 b2 88 fb 57 36 54 83 c8 23 eb c5 74 da 70 c5 94 7f 4a 07 1d cb 2c 3e 53 58 77 1c ca 45 6e 37 dd 35 89 38 fd e9 a1 97 2d 88 76 d1 8a 76 29 c8 bb 98 52 32 23 da 4f 6a 96 38 01 19 6e 95 21 c0 e0 0a 98 0d d1 0c 75 14 0a c4 b6 d1 a0 8f 81 8c d3 9d 76 1a 92 24 21 00 a8 e7 38 fc 29 9b c7 62 85 c9 dc f8 f4 aa f8 a7 bb 65 89 a6 1e b4 8c a5 ab 0a 43 41 a6 f7 a0 43 5e 95 54 e0 50 06 48 06 a4 c7 14 0e 28 85 86 2a 32 78 a9 5e a0 90 e0 52 35 7b 12 e2 81 4b 8e 69 71 4c 60 bd 6a 74 a8 50 73 53 31 c0 da 3a d0 00 cd b8 e0 74 14 a0 8c e3 bd 20 18 1c 75 a6 a9 cb 8d c3 9c d3 02 c4 7c 1a b8 83 8a aa 8a 59 b8 ab 89 c0 02 80 1e 38 a5 52 41 e2 90 0a 51 40 0f f3 1b 34 ed e1 ba f5 a8 a9 71 40 12 16 e3 02 a2 75 ca 9a 78 a5 c1 34 01 45 46 3a d4 8b 43 ae d9 0f bd 0b 40 89 00 14 f0 05 31 4d 48 a2 81 8e db 9a 70 5a 45 19 a9 00 a6 16 1a 12 83 1e 6a 40 29 c1 68 15 91 58 db 46 df 79 14 fe 15 24 71 88 d7 6a 8c 01 da a6 c5 21 5a 01 22 0d 0a 2a 4b 57 00 0f 00 01 82 03 00 00 0d 0a ";
// String raw_DeviceId = sb.substring(38, 1040);
// byte[] b = HexStringToByteArray(hex);
//// imageInFile.read(b);
// for (int i = 0; i < b.length; i++) {
// byte c = b[i];
// System.out.println("c = " + c);
//
// }
Font font = new Font("Arial", Font.PLAIN, 12);
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics(font);
g2d.dispose();
int width = fm.stringWidth(hex);
int height = fm.getHeight();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(hex, 0, fm.getAscent());
g2d.dispose();
try {
ImageIO.write(img, "jpg", new File("Hex.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
You have a kind of chicken and egg issue. In order to generate the image, you will need to know how big to make the image. In order to calculate this information, you will need a Graphics context from an image in order to ascertain the FontMetrics for the given Graphics context...
The following example simple creates a 1x1 BufferedImage which is used to obtain a reference to the FontMetrics, which is used to calculate the required width/height of the String in question.
This is then used to create a new instance of the BufferedImage at the correct size and the String is rendered to it.
It is then saved to a jpg file...
A small snippet of the output image...
String hex="ff d8 ff e0 00 11 4a 46 49 46 00 01 01 01 00 00 00 00 00 00 0a ff db 00 43 00 08 06 06 07 06 05 08 07 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 0f 14 1d 1a 1f 1e 1d 1a 1c 1c 20 24 2e 27 20 22 2c 23 1c 1c 28 37 29 2c 30 31 34 34 34 1f 27 39 3d 38 32 3c 2e 33 34 32 ff db 00 43 01 09 09 09 0c 0b 0c 18 0d 0d 18 32 21 1c 21 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 42 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a 83 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 f2 f3 f4 f5 f6 f7 f8 f9 fa ff c4 00 1f 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 a1 b1 c1 09 23 33 52 f0 15 62 72 d1 0a 16 24 34 e1 25 f1 17 18 19 1a 26 27 28 29 2a35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65";
Font font = new Font("Arial", Font.PLAIN, 12);
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics(font);
g2d.dispose();
int width = fm.stringWidth(hex);
int height = fm.getHeight();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(hex, 0, fm.getAscent());
g2d.dispose();
try {
ImageIO.write(img, "jpg", new File("Hex.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}

Project Euler #11 java. Not getting the right answer

I have some problems with Problem 11 on Project Euler.
I manage to get an answer, but it's not the right one. I'm getting 51267216.
This is found by the greatestVert method. I think the problem is located in the greatestDiaglonal method, but I'm not quite sure. Can somebody check if my algorithm is correct?
The task is to find out what the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally) is in the 20x20 grid.
package euler;
public class Problem11 {
int num1, num2, num3, num4;
int highestNum1, highestNum2, highestNum3, highestNum4;
private int sum = 0;
String[] l = {
"08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08",
"49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00",
"81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65",
"52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91",
"22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80",
"24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50",
"32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70",
"67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21",
"24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72",
"21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95",
"78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92",
"16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57",
"86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58",
"19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40",
"04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66",
"88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69",
"04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36",
"20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16",
"20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54",
"01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"
};
int greatestSide() {
for(int i = 0;i<=19;i++) {
for(int n = 0;n<=l[i].length()-12;n+=3) {
num1 = Integer.parseInt(l[i].substring(0+n,3+n).trim());
num2 = Integer.parseInt(l[i].substring(3+n,6+n).trim());
num3 = Integer.parseInt(l[i].substring(6+n,9+n).trim());
num4 = Integer.parseInt(l[i].substring(9+n,12+n).trim());
if(num1*num2*num3*num4 > sum) {
sum = num1*num2*num3*num4;
highestNum1 = num1;
highestNum2 = num2;
highestNum3 = num3;
highestNum4 = num4;
}
}
}
return sum;
}
int greatestVert() {
for(int i = 0; i<=16; i++) {
for(int n = 0; n<=l[i].length()-3; n+=3) {
num1 = Integer.parseInt(l[i].substring(0+n,3+n).trim());
num2 = Integer.parseInt(l[i+1].substring(0+n,3+n).trim());
num3 = Integer.parseInt(l[i+2].substring(0+n,3+n).trim());
num4 = Integer.parseInt(l[i+3].substring(0+n,3+n).trim());
if(num1*num2*num3*num4 > sum) {
sum = num1*num2*num3*num4;
highestNum1 = num1;
highestNum2 = num2;
highestNum3 = num3;
highestNum4 = num4;
}
}
}
return sum;
}
int greatestDiagonal() {
for(int i = 19; i>=3; i--) {
for(int n = 0; n<=l[i].length()-12; n+=3) {
num4 = Integer.parseInt(l[i].substring(9+n,12+n).trim());
num3 = Integer.parseInt(l[i-1].substring(6+n,9+n).trim());
num2 = Integer.parseInt(l[i-2].substring(3+n,6+n).trim());
num1 = Integer.parseInt(l[i-3].substring(0+n,3+n).trim());
if(num1*num2*num3*num4 > sum) {
sum = num1*num2*num3*num4;
highestNum1 = num1;
highestNum2 = num2;
highestNum3 = num3;
highestNum4 = num4;
}
}
}
for(int i = 0; i>=16; i++) {
for(int n = 0; n<=l[i].length()-12; n+=3) {
num4 = Integer.parseInt(l[i].substring(9+n,12+n).trim());
num3 = Integer.parseInt(l[i+1].substring(6+n,9+n).trim());
num2 = Integer.parseInt(l[i+2].substring(3+n,6+n).trim());
num1 = Integer.parseInt(l[i+3].substring(0+n,3+n).trim());
if(num1*num2*num3*num4 > sum) {
sum = num1*num2*num3*num4;
highestNum1 = num1;
highestNum2 = num2;
highestNum3 = num3;
highestNum4 = num4;
}
}
}
return sum;
}
public static void main(String[] args) {
Problem11 prog = new Problem11();
prog.greatestSide();
prog.greatestVert();
prog.greatestDiagonal();
System.out.println(prog.sum);
System.out.println(prog.highestNum1);
System.out.println(prog.highestNum2);
System.out.println(prog.highestNum3);
System.out.println(prog.highestNum4);
}
}
You are omitting to scan one direction of diagonals:
for(int i = 0; i>=16; i++) {
doesn't run at all. You meant i <= 16 there.
Here is another solution that firstly converts the String to a 2D array:
public class P11 {
public static void main(String[] args) throws Exception {
String input = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
int n = 20;
int a[][] = getMatrixOfIntegers(input, n);
System.out.println(maxProduct(a));
}
private static long maxProduct(int a[][]) {
int size = a.length - 4;
int l = a.length - 1;
long pMax = 1;
for ( int i = 0 ; i < size ; i++ ) {
for ( int j = 0 ; j < size ; j++ ) {
int prodDiag1 = a[i][j]*a[i+1][j+1]*a[i+2][j+2]*a[i+3][j+3];
if ( pMax < prodDiag1 ) {
pMax = prodDiag1;
}
int prodCol = a[i][j]*a[i+1][j]*a[i+2][j]*a[i+3][j];
if ( pMax < prodCol ) {
pMax = prodCol;
}
int prodRow = a[i][j]*a[i][j+1]*a[i][j+2]*a[i][j+3];
if ( pMax < prodRow ) {
pMax = prodRow;
}
int prodDiag2 = a[i][l-j]*a[i+1][l-j-1]*a[i+2][l-j-2]*a[i+3][l-j-3];
if ( pMax < prodDiag2 ) {
pMax = prodDiag2;
}
}
}
return pMax;
}
private static int[][] getMatrixOfIntegers(String input, int n) {
String m[] = input.split(" ");
int a[][] = new int[n][n];
for ( int i = 0 ; i < n*n ; i++ ) {
a[i/n][i%n] = Integer.parseInt(m[i]);
}
return a;
}
}
Time for maxProduct: 0.2 ms

Categories