Converting text to binary in java - java

I want to convert every character of a String to a new binary String. Here is what I do :
public static void main(String args[]) {
String MESSAGE = "%";
String binaryResult = "";
for (char c : MESSAGE.toCharArray()){
binaryResult += Integer.toBinaryString( (int) c);
}
System.err.println(binaryResult);
}
For exemple with the input : "%", I get the following output : "100101"
My problem is that the leading "0" is deleted ...
I want to have : "0100101". Does anyone have ideas?

What you're really saying is "How can I pad my binary string representation of a character to 7 digits"?
Replace this line:
binaryResult += Integer.toBinaryString( (int) c);
With these:
String binString = Integer.toBinaryString( (int) c );
binaryResult += ("0000000" + binString).substring(binString.length());
This presumes that you only have 7-bit characters... if you need more, then add 0's to the "00000" string to match the length of string (with padded 0s) you want.

I would suggest a couple of changes to your existing code. Since, you are concatenating to an string, inside a loop, this would cause the creation of a bunch of new string objects since they are immutable. The problem may be solved by use of a StringBuilder.
public static void main(String args[]) {
String MESSAGE = "%";
StringBuilder binaryResult = new StringBuilder();
for (char c : MESSAGE.toCharArray()) {
StringBuilder curValue = new StringBuilder(Integer.toBinaryString((int)c));
// calculate padding 0 bits to fill to 8 bits
int paddingLength = 8 - curValue.length();
char[] paddingArr = new char[paddingLength];
Arrays.fill(paddingArr, '0');
// insert padding bytes to the front
curValue.insert(0, paddingArr);
// add to stringbuilder for `MESSAGE`
binaryResult.append(curValue);
}
System.err.println(binaryResult.toString());
}

Related

Unable to call a .dll function correclty

I am calling a shared .dll function using JNA Java. From the documentation, the function can be invoked to receive parameters using Visual C++ as below;
PMSifEncodeKcdLcl(PCHAR ff, PCHAR Dta, BOOL Dbg, PCHAR szOpId, PCHAR szOpFirst, PCHAR szOpLast);
From the doc:
ff - A single ASCII character.
Dta - Points to a null-terminated string.
Dbg - a boolean flag
szOpId - points to a null-terminated string
szOpFirst - points to a null-terminated string
szOpLast - points to a null-terminated string
The string is built from a number of Data Fields. The format for each Data Field within the string is as follows:
RS FI data
RS = Record Separator.
Indicates the start of the Data Field. A single ASCII Record Separator [RS] character (hex 1E)
FI = Field Identifier - Indicates the type of data in the field. A single ASCII character.
data = the actual data. A number of ASCII characters, dependent on the Field Identifier. Sometimes the data is variable in length. The Record Separator of the following field indicates the end of a Data Field (or for the last field, the NULL character at the end of the string).
An Answer Code is returned in field ff. Answer Data (if any) is returned in field Dta
I have cross checked the JNA documentation to confirm field mappings but still no success. After trying for days. I came up with the code below;
My Java Code:
/* JNA interface class
*/
public class JNALocksInterface {
public interface LockLibrary extends StdCallLibrary {
LockLibrary INSTANCE = (LockLibrary) Native.loadLibrary("path_to_dll", LockLibrary.class);
public void PMSifEncodeKcdLcl(byte[] ff, byte[] dta, boolean debug, String szOpid, String szOpFirst, String szOpLast);
}
}
/*My Calling Class Code*/
JNALocksInterface.LockLibrary INSTANCE = JNALocksInterface.LockLibrary.INSTANCE;
String dta = "*R101*L101*TSingle Room*NMatu*FZachary*URegular Guest*D201805021347*O201805030111";
String ff = "A";
byte[] dataBytes = new byte[dta.length() + 1];
System.arraycopy(dta.getBytes("UTF-8"), 0, dataBytes, 0, dta.length());
dataBytes[dta.length()] = 0;
byte[] dtaByteArray = new byte[dta.length() + 1];
byte[] ffByteArray = ff.getBytes("UTF-8");
for (int i = 0; i < dataBytes.length; i++) {
String s1 = String.format("%8s", Integer.toBinaryString(dataBytes[i] & 0xFF)).replace(' ', '0');
// System.out.println(s1);
if((char)dataBytes[i] == '*')
{
dtaByteArray[i] = 30;
}
else{
int val = Integer.parseInt(s1, 2);
byte b = (byte) val;
dtaByteArray[i] = b;
}
}
byte[] commandCodeFinal = new byte[1];
for (int i = 0; i < ffByteArray.length; i++) {
String s2 = String.format("%8s", Integer.toBinaryString(ffByteArray[i] & 0xFF)).replace(' ', '0');
System.out.println(s2);
int val = Integer.parseInt(s2, 2);
byte b = (byte) val;
commandCodeFinal[i] = b;
}
String userNameBytes = "test";
String userFirstNameBytes = "test";
String userLastNameBytes = "test";
INSTANCE.PMSifEncodeKcdLcl(commandCodeFinal, dtaByteArray, false, userNameBytes, userFirstNameBytes, userLastNameBytes);
I am getting a wrong response on field ff and dta as shown below.
FF Response >> :
DTA Response >> 0101IR101L101TSingle RoomNMatuFZacharyURegular GuestD201805021347O2018050
I am replacing "*" with the ascii record separator.
Can someone show me how to correctly call the function using JNA? I've searched all over but still no success.
Solved IT. Used Unicode Field separator and used JNA Memory object and it Worked!
Was also using WIndows 10 64 bit. Changed to Windows 7 32 bit and it worked!!
Replaced the code with below snippet;
String fieldSeparator = "\u001e"
String dataTest = fieldSeparator+"R101"+fieldSeparator+"TSingle Room"+fieldSeparator+"FShujaa"+fieldSeparator+"NMatoke"
+ fieldSeparator+"URegular Guest"+fieldSeparator+"D201805040842"+fieldSeparator+"O201805051245";
String dataTestPadded = org.apache.commons.lang.StringUtils.rightPad(dataTest,30,'0');
System.out.println("Padded string >> " + dataTestPadded);
String data = dataTest;
//getPayloadToSend(payLoadSample) + (char)00;
String commandCode = "A";
Memory commandCodeMemory = new Memory(commandCode.length()+1);
commandCodeMemory.setString(0, commandCode);
Memory dataMemory = new Memory(data.length()+1);
dataMemory.setString(0, data);
//dataMemory.setString(1, "0");
System.out.println("Registerring >> " + INSTANCE.PMSifRegister("42860149", "BatchClient")) ;
INSTANCE.PMSifEncodeKcdLcl(commandCodeMemory, dataMemory, false, "ZKMATU", "zACHARY", "tESTING");
System.out.println("FF Response >> " + commandCodeMemory.getString(0));
System.out.println("DTA Response >> " + dataMemory.getString(0));
INSTANCE.PMSifUnregister();

Java Replace substring in String with exact number of character

My string is "test"
"test" has 4 characters
I want to replace "test" with "****"
so I get "****"
My code
System.out.println("_test_");
System.out.println("_test_".replaceAll("test", "*"));
But it replace test with 1 *.
If the word test is just an example, you may use Matcher.appendReplacement (see How to appendReplacement on a Matcher group instead of the whole pattern? for more details on this technique):
String fileText = "_test_";
String pattern = "test";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(fileText);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, repeat("*", m.group(0).length()));
}
m.appendTail(sb); // append the rest of the contents
System.out.println(sb);
And the repeat function (borrowed from Simple way to repeat a String in java, see other options there) SO post is:
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
See IDEONE demo
If you have an arbitrary text to be replaced, and you want to use replaceAll(), be aware that it takes a regular expression, and various characters have special meaning. To prevent issues, call Pattern.quote().
Also, to replace with a sequence of * of equal length, you need to build a string of such.
Here is a nice short method for doing it:
private static String mask(String input, String codeword) {
char[] buf = new char[codeword.length()];
Arrays.fill(buf, '*');
return input.replaceAll(Pattern.quote(codeword), new String(buf));
}
Test
System.out.println(mask("_test_", "test"));
System.out.println(mask("This is his last chance", "is"));
Output
_****_
Th** ** h** last chance
Yes, because replaceAll(str1, str2) will replace all occurrences of str1 with str2. Since you are using literals, you need to say
System.out.println("_test_".replaceAll("test", "****"));
If you want your own replacement function you can do something like this:
public static String replaceStringWithChar(String src, String seek, char replacement)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < seek.length(); i++) sb.append(replacement);
return src.replaceAll(seek, sb.toString());
}
You would then call it like so:
replaceStringWithChar("_test_", "test", '*');
So I got the answer and I was really looking for
something with as few line as possible. Thank you all
for the answer but this is the answer I found most useful.
I apologize for not being clear in the question, if I was not.
String str1 = "_AnyString_";
int start_underscore = str1.indexOf("_");
int end_underscore = str1.indexOf("_", start_underscore + 1);
String str_anything = str1.substring(start_underscore + 1, end_underscore);
String str_replace_asterisk = str_anything.replaceAll(".", "*");
System.out.println(str_replace_asterisk);
str1 = str1.replace(str_anything, str_replace_asterisk);
System.out.println(str1);
Output:
_AnyString_
_*********_
Actually you are pretty close the what you want. This is what you can do:
System.out.println("_test_".replaceAll("[test]", "*"));
System.out.println("hello".replaceAll("[el]", "*"));
Output:
_****_
h***o

Encode only specific characters in String

I have to encode only some special characters in a string to numeric value.
Say,
String name = "test $#";
I want to encode only characters $ and # in the above string. I tried using below code but it did not work out.
String encode = URLEncoder.encode(StringEscapeUtils.escapeJava(name), "UTF-8");
The encoded value will be like, for white space the encoded value is &#160
What about to split that String (by string#split method - with space as regex), from Array, which it returns you can use last item and you will get there symbols, what you need :)
String name = "test $#";
String nameSplittedArr = name.split(" ");
String yourChars = nameSplittedArr[nameSplittedArr.length-1]; //indexes from zero
That should works :)
As per the comments, I think you are after a customized encoding function. Something like:
public static String EncodeString(String text) {
StringBuffer sb = new StringBuffer();
for (char c : text.toCharArray()) {
if (Character.isLetterOrDigit(c)) {
sb.append(c);
} else {
sb.append("&#" + (int)c + ";");
}
}
return sb.toString();
}
An example of this is here.

How do you rebuild a string using StringBuilder?

Im trying to rebuild a string using StringBuilder. I'm a little unsure of which method to use to get the "'," inserted back into the same place. In the code below I'm using the
"insert(int dstOffset, CharSequence s, int start, int end)" method. My code doesn't contain any errors however it doesn't run properly.
Please note I will also be escaping characters (i.e., =) in the string but I havent written that part of the code yet. Currently I'm trying to learn how to split the string and then rebuild it.
Thanks
public class StringTestProgram
{
public static void main(String[] args)
{
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
for (String stringoutput : stringData)
{
System.out.print(stringoutput);
StringBuilder sb = new StringBuilder(stringoutput);
CharSequence charAdded = ",";
sb.insert(6,charAdded,0,12);
System.out.print(sb.toString());
}
}
}
Revised code
public class StringTestProgram {
public static void main(String[] args) {
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
System.out.println(relativeDN);
//Split String
String[] stringData = relativeDN.split(",");
{
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
// loop thru each element of the array
for (int place = 0; place < stringData.length; place++) {
System.out.println(stringData[place]);
{
int eq = relativeDN.indexOf('=');
String sub = relativeDN.substring(0, eq);
System.out.println(sub);
}
// append element to the StringBuilder
sb.append(stringData[place]);
// avoids adding an extra ',' at the end
if (place < stringData.length - 1)
// if not at the last element, add the ',' character
sb.append(charAdded);
}
System.out.print(sb.toString());
}
}
}
Im new to stackoverflow and I'm not sure if its ok to ask this question in this thread or if I should create a seperate thread for this question. If possible please advise.
The code above now splits the string at the "," character. It also rebuilds the
string back to its original state. I would also like to use the indexof and .substring
methods to get the string value after the "=" sign. Currently my program only outputs
the first two characters of the initial string value before the "=" sign. Not sure where
in my code I'm making an error. Any help would be appreciated.
My Current Output
cn=abc,dn=xyz,ou=abc/def
cn=abc
cn
dn=xyz
cn
ou=abc/def
cn
cn=abc,dn=xyz,ou=abc/def
Desired Output
cn=abc,dn=xyz,ou=abc/def
cn=abc
abc
dn=xyz
xyz
ou=abc/def
abc/def
cn=abc,dn=xyz,ou=abc/def
The easiest way to do this pre Java 8 is to use 1 StringBuilder for all the elements and add Strings to the builder by using the append() method
StringBuilder builder = new StringBuilder();
for (String stringoutput : stringData) {
builder.append(stringoutput).append(',');
}
//have an extra trailing comma so remove it
//use length -1 as end coord because it's exclusive
String result = builder.substring(0, builder.length() -1);
If you are using Java 8 you can use the new Stream API and Collectors.joining()
String result = Arrays.stream(relativeDN.split(","))
.collect(Collectors.joining(","));
You're initializing sb every time you enter the loop, meaning that you're disposing of your StringBuilder every time you enter the loop and recreate it with only the next subtring.
Fixed:
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
for (String stringoutput : stringData) {
System.out.print(stringoutput);
sb.append(stringoutput).append(charAdded);
}
sb.setLength(sb.length() - 1);
System.out.print(sb.toString());
Try out this code
public class StringTestProgram {
public static void main(String[] args) {
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
for (int i = 0; i < stringData .length; i++) { //walk over each element of the array
System.out.println(stringData[i]);
sb.append(stringData[i]); // append element to the StringBuilder
if (i < stringData.length - 1) //avoids adding an extra ',' at the end
sb.append(charAdded); // if not at the last element, add the ',' character
}
System.out.print(sb.toString());
}
}
Here you will reconstruct the original string exactly as it was (i.e. without adding a trailing ','):
cn=abc,dn=xyz,ou=abc/def
UPDATE: In the for loop I just walk over every element of the array that stores the splitted String and append the elements to the StringBuilder instance one by one. After appending each element I check if we are currently at the last element of the array. If not, I append the ',' character.
Like this:
for (String stringoutput : stringData)
sb.append(stringoutput).append(',');
Fixed: Using this approach, you would have to remove the last ,
String result = sb.toString().substring(0,sb.toString().length()-1);
System.out.println(result);
I noticed in the other answers that there would be an extra comma at the end. You have to use a prefix variable and then change it in the loop so that there won't be an extra comma.
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
String prefix = "";
for (String element : stringData) {
sb.append(prefix);
prefix=",";
sb.append(element);
}
String output = sb.toString();
Inside the loop the prefix is appended, but on the first time through the loop the prefix is set to empty quotes so that there won't be a comma before the first element. Next prefix is changed to a comma so that in the next turn through the loop a comma will be added after the first element. Lastly, the element is added. This results in the correct output because the comma is added before the element, but only after the first iteration.

Insert a character before and after all letters in a string in Java

I want to insert a % character before after every letter in a string, but using StringBuilder to make it fast.
For example, if a string is 'AA' then it would be '%A%A%'. If it is 'XYZ' then it would be '%X%Y%Z%'
String foo = "VWXYZ";
foo = "%" + foo.replaceAll("(.)","$1%");
System.out.println(foo);
Output:
%V%W%X%Y%Z%
You don't need a StringBuilder. The compiler will take care of that simple concatenation prior to the regex for you by using one.
Edit in response to comment below:
replaceAll() uses a Regular Expression (regex).
The regex (.) says "match any character, and give me a reference to it" . is a wildcard for any character, the parenthesis create the backreference. The $1 in the second argument says "Use backreference #1 from the match".
replaceAll() keeps running this expression over the whole string replacing each character with itself followed by a percent sign, building a new String which it then returns to you.
Try something like this:
String test = "ABC";
StringBuilder builder = new StringBuilder("");
builder.append("%");
for (char achar : test.toCharArray()) {
builder.append(achar);
builder.append("%");
}
System.out.println(builder.toString());
public static String escape(String s) {
StringBuilder buf = new StringBuilder();
boolean wasLetter = false;
for (char c: s.toCharArray()) {
boolean isLetter = Character.isLetter(c);
if (isLetter && !wasLetter) {
buf.append('%');
}
buf.append(c);
if (isLetter) {
buf.append('%');
}
wasLetter = isLetter;
}
return buf.toString();
}
StringBuilder sb = new StringBuilder("AAAAAAA");
for(int i = sb.length(); i >= 0; i--)
{
sb.insert(i, '%');
}
You may see this.
String s="AAAA";
StringBuilder builder = new StringBuilder();
char[] ch=s.toCharArray();
for(int i=0;i<ch.length;i++)
{
builder.append("%"+ch[i]);
}
builder.append("%");
System.out.println(builder.toString());
Output
%A%A%A%A%
I agree with #Brian Roach to add character to before and after but if you want to add any specific character then do like this
String source = "hello good old world";
StringBuffer res = new StringBuffer();
String[] strArr = tagList.split(" ");
for (String str : strArr) {
char[] stringArray = str.trim().toCharArray();
stringArray[0] = stringArray[0];
str = new String(stringArray);
//here you need to specify your first and last character which you want to set
res.append("#"+ str + "$").append(" ");
}
System.out.println("Result: " + res.toString().trim());
Output :- #hello$ #good$ #old$ #world$

Categories

Resources