I'm trying to put the data which is read from sequence file, and put it into Hash Map. After the loop finished, I try to print the content which is wrong.
I've tried to just print the key and value in the first loop, and the result is correct. When I try to print the key in the second while loop, the result is several duplicate records. I can't figure it out what is going wrong.
while(reader.next(key, value)) {
byte[] value_bytes = value.getBytes();
data_HashMap.put(key, value_bytes);
}
IOUtils.closeStream(reader);
Iterator<Text> keySetIterator = data_HashMap.keySet().iterator();
while(keySetIterator.hasNext()){
Text index = keySetIterator.next();
System.out.println("key: " + index);
}
here is the result
Key: 123
Key: 123
Key: 123
Key: 123
Key: 123
Key: 123
If I modified the first while loop like this
while(reader.next(key, value)) {
byte[] value_bytes = value.getBytes();
System.out.println("Key: " + key);
}
Here is the result and it's correct.
Key: 123
Key: 456
Key: 789
Key: 741
Key: 852
Key: 963
You are reusing the same key all over again:
while(reader.next(key, value)) {
byte[] value_bytes = value.getBytes();
data_HashMap.put(**key**, value_bytes);
}
I don't know what the type is, but if it's Text, simply copy it or use String instead.
while(reader.next(key, value)) {
byte[] value_bytes = value.getBytes();
data_HashMap.put(key.toString(), value_bytes);
}
You will hit the same issue with the value bytes as well, so I recommend you to do a defensive copy of this array too.
Related
I have a string than I want to encrypt to send it over an insecure channel.
I want to:
Convert to int my-val & my-private-key. Then, multiply both. Send it. When receiving it, divide by my-private-key converted as int and get my-val.
I tried to used Integer.parseInt and Integer.toString as suggested here. It seems to work with System.out.println(Integer.parseInt("Kona", 27)); (as Java's documentation said)
So I made this:
int base = 27;
String key = "some key";
String cmd = "some val";
int based = Integer.parseInt(cmd, base);
System.out.println("Based: " + based);
int crypted = based * Integer.parseInt(key, base);
System.out.println("Crypted: " + crypted);
// here use un-secure channel to send/receive
int received = crypted;
int back = received / Integer.parseInt(key, base);
System.out.println("Get back: " + back);
System.out.println("Final result: " + Integer.toString(back, base));
But I get Exception in thread "main" java.lang.NumberFormatException: For input string: "some val" at the 4st line.
I tried with base 10, 16, 27, 32. Even if I understand why 10 & 16 doesn't work, why 27 & 32 don't ? How can I fix it ?
Based on below wikipedia link of numeral system, Java will check each character of your input string against the range of radix parameter and if its not in range than it will throw exception.
Visit https://en.wikipedia.org/wiki/List_of_numeral_systems,
Apart from that, Below is explanation from geeksforgeek site.
The string is null or of zero-length
The value represented by the string is not a value of type int
Specifically for the parseInt(String s, int radix) variant of the function:
The second argument radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX
*
Each character of input string has min and max radix parameter.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign ‘-‘ (‘\u002D’) or plus sign ‘+’ (‘\u002B’) provided that the string is longer than length 1
Custom logic for conversion
String name = "some val";
long key = 0;
for (int i = 0;i<name.length();i++)
key+= (name.charAt(i) - 'a'+1 ) * Math.pow(26,name.length() - i - 1 );
System.out.println(key);
Above code is taken Converting name to a key using radix-26
I was looking to encrypt with another string. I get the idea to multiply both, and so convert them into int. But, it seems to have informations lost with operation.
So, I searched for another way, and I found this one:
private static final String ALGORITHM = "AES";
private static final Key MY_KEY = new SecretKeySpec("16-char priv key".getBytes(), ALGORITHM);
private Cipher getCipher(int mode) throws Exception {
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(mode, MY_KEY);
return c;
}
public String encrypt(String valueToEnc) throws Exception {
return Base64.getEncoder().encodeToString(getCipher(Cipher.ENCRYPT_MODE).doFinal(valueToEnc.getBytes()));
}
public String decrypt(String encryptedValue) throws Exception {
return new String(getCipher(Cipher.DECRYPT_MODE).doFinal(Base64.getDecoder().decode(encryptedValue)));
}
How it works ? It encrypt and decrypt with a key. This key should be a 16-chars one. Also, to make it easier to show/send/receive, it's converted into base 64.
Example of how to use:
String myVal = "some val";
String encrypt = encrypt(myVal);
System.out.println("Encrypt: " + encrypt);
String decrypt = decrypt(encrypt);
System.out.println("Decrypt: " + decrypt);
Output:
Encrypt: ERJZ7ZOJcNpQEAvrb6wPOA==
Decrypt: some val
Trying to print data to a gui made by javafx.
...
for(Entry<Date, String> entry : tmap.entrySet()) {
Date key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " => " + value);
I do not want to use setText() as it wont act like in console, it will clear to only one text every loop of TreeMap
The only way to do this is by concatenating the original text with the new content and setting the resulting String using setText.
In your case you can improve the efficiency of doing this by using a StringBuilder:
StringBuilder sb = new StringBuilder(textNode.getText());
for(Entry<Date, String> entry : tmap.entrySet()) {
Date key = entry.getKey();
String value = entry.getValue();
sb.append(key).append(" => ").append(value).append('\n');
...
}
textNode.setText(sb.toString());
In case you're using a TextInputControl, appendText may be worth a look, but in case you know you're adding multiple Strings, StringBuilder is probably more efficient.
for(Entry<Date, String> entry : tmap.entrySet()) {
Date key = entry.getKey();
String value = entry.getValue();
textNode.appendText(key + " => " + value + '\n');
...
}
I have a long string containing different values/strings i want to extract.
String info = "ABHom=1.00;AC=2;AF=1.00;AN=2;DP=24;Dels=0.00;FS=0.000;
HaplotypeScore=0.9947;MLEAC=2;MLEAF=1.00;MQ=53.03;MQ0=0;QD=32.49;
VQSLOD=2.70; culprit=FS";
Matcher matcher = Pattern.compile("[A][B][h][o][m][=]([0-9]+\\.[0-9]+)").matcher(info);
if (matcher.find()) {
String someNumberStr = matcher.group(1);
ABhom = Double.parseDouble(someNumberStr);
Matcher matcher = Pattern.compile("[M][L][E][A][C][=]/([0-9]+)").matcher(info);
if (matcher.find()) {
String someNumberStr = matcher.group(1);
MLEAC = Integer.parseInt(someNumberStr);
I'am new to regex. Is there any smarter way to extract the numbers/strings after the equals sign ?
I'am thankful for any suggestions!
I think what you want to do is to turn your String into a HashMap<String,String>.
First, you'll need to split your string around semicolons. Then, iterate the array that you get, splitting each entry around the equals sign, and adding the result to the HashMap.
I suggest you read about the split method of the String class for how to do this, and also read about the HashMap class. Look at http://docs.oracle.com/javase/7/docs/api/java/lang/String.html and http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html and post again if you need more help.
You can do like this
String[] split = info.split(";");
for (String string : split) {
String[] split2 = string.trim().split("=");
System.out.println(split2[0] +" :" +split2[1]);
}
You can store them in HashMap as follows:
String[] parts = info.split(";");
Map<String, String> hashMap = new HashMap<String, String>();
for (String s : parts) {
String[] keyVal = s.trim().split("=");
hashMap.put(keyVal[0], keyVal[1]);
}
and later on you may use hashMap object to get it's values.
String info = "ABHom=1.00;AC=2;AF=1.00;AN=2;DP=24;Dels=0.00;FS=0.000;"
+ " HaplotypeScore=0.9947;MLEAC=2;MLEAF=1.00;MQ=53.03;MQ0=0;QD=32.49;"
+ "VQSLOD=2.70; culprit=FS";
Pattern pattern = Pattern.compile("(\\w+)=(\\d+(.\\d+)?)");
Matcher matcher = pattern.matcher(info);
while (matcher.find()) {
System.out.println("key: "+matcher.group(1) +" value: "+matcher.group(2));
}
output :
key: ABHom value: 1.00
key: AC value: 2
key: AF value: 1.00
key: AN value: 2
key: DP value: 24
key: Dels value: 0.00
key: FS value: 0.000
key: HaplotypeScore value: 0.9947
key: MLEAC value: 2
key: MLEAF value: 1.00
key: MQ value: 53.03
key: MQ0 value: 0
key: QD value: 32.49
key: VQSLOD value: 2.70
explanation :
\\w mean any character include _ \\w+ means array of characters
\\d mean any digit \\d+ means array of digits
? Matches the preceding element zero or one time. For example, ab?c matches only "ac" or "abc".
you said that i want to extract string and numbers , because of this the code above can not extract culprit=FS but if you want to extract all pair you should use this code :
Pattern pattern = Pattern.compile("(\\w+)=([^;]+)");
Matcher matcher = pattern.matcher(info);
while (matcher.find()) {
System.out.println("key: "+matcher.group(1) +" value: "+matcher.group(2));
}
output :
key: ABHom value: 1.00
key: AC value: 2
key: AF value: 1.00
key: AN value: 2
key: DP value: 24
key: Dels value: 0.00
key: FS value: 0.000
key: HaplotypeScore value: 0.9947
key: MLEAC value: 2
key: MLEAF value: 1.00
key: MQ value: 53.03
key: MQ0 value: 0
key: QD value: 32.49
key: VQSLOD value: 2.70
key: culprit value: FS
I don't think regex is a good idea. Try info.split(";")[0].split("=")[1] with some extra boundary check.
I have a string which contains a value:
12345 5
54321 4
98765 10
The first value is a number, the second value is a count. The string value is obtained by this code:
for(ClusterListBean bean : clusterList) {
line += bean.getMSISDN()+"\t"+bean.getRewardCount()+"\n";
}
Now I am reading a file which has same contents but different count value.
This is accomplished by:
BufferedReader ln = FileCreatorUtil.readFile(configFileUtil.prevFile().getFileDir()+prevFile.clusterPrevFile().getFileName());
Now what I want to do is to search for a number value, get the count paired with it, and subtract the count. Example:
BufferedReader ln contents:
12345 5
54321 4
98765 10
String line contents:
12345 7
54321 9
98765 15
Output should be:
12345 2
54321 5
98765 5
Put your data into a HashMap where MSISDN is key and count is value. Reading second file consult that map and subtract the value.
Why don't you put your "Strings" in a hashmap?
Map<String,Integer> map = new HashMap<String,Integer>();
for(ClusterListBean bean : clusterList) {
map.put(bean.getMSISDN(),bean.getRewardCount());
}
then read your file:
BufferedRead ln = null;
try{
ln = new BufferedReader(new FileReader(configFileUtil.prevFile().getFileDir()+prevFile.clusterPrevFile().getFileName()));
String line;
while((line=br.readLine())!=null){
String[] linesplit = line.split("\\t");
if (map.containsKey(linesplit[0])){
//do whatever you need with something like:
System.out.println(map.get(linesplit[0])-Integer.parseInt(linesplit[1]));
}
}
ln.close();
}catch(IOException e){
e.printStackTrace();
}
i need some help and guidance in displaying the splitted Strings in order.
let say, i have username, password, nonceInString. i had successfully encrypted and decrypted those. then i split the decrypted data. it was done, too.
i want to display the decrypted data in order.
something like this.
userneme: sebastian
password: harrypotter
nonce value: sdgvay1saq3qsd5vc6dger9wqktue2tz*
i tried the following code, but it didn't display like i wish to.
pls help. thanks a lot in advance.
String codeWord = username + ";" + password + ";" + nonceInString;
String encryptedData = aesEncryptDecrypt.encrypt(codeWord);
String decryptedData = aesEncryptDecrypt.decrypt(encryptedData);
String[] splits = decryptedData.split(";");
String[] variables = {"username", "password", "nonce value"};
for (String data : variables){
for (String item : splits){
System.out.println( data + ": "+ item);
}
}
Your nested for-each logic is wrong; instead, you need to explicitly pair up the elements of the array by an index:
for (int i = 0; i < variables.length; i++) {
System.out.println(variables[i] + ":" + splits[i]);
}
Note that this assumes that both arrays have the same lengths, and will throw an ArrayIndexOutBoundsException if the splits array is shorter than the variables array.
As a side note, for key-value mapping data structure, you may want to look at java.util.Map.
import java.util.*;
//...
Map<String,String> map = new HashMap<String,String>();
map.put("username", "sebastian");
map.put("password", "harrypotter");
System.out.println(map); // prints "{username=sebastian, password=harrypotter}"
System.out.println(map.get("password")); // prints "harrypotter"
thats because your inner loop will loop through all the values in splits for each element in variables.
i assume you got something like
username ..
username ..
username ..
password ..
pa....