Related
I have a base64 encoded String p12 file which is return by an API. I am trying to save it to file but won't work when I am opening it on my mobile phone.
What went wrong:
After decoding the string and saving it to a .p12 file. The file cannot be opened as it seems to be corrupted. I am trying to find another way to decode a base64 string to make it work.
What I've tried:
Call the API to get the Base64 encoded String
Decode it using the following code I got while searching (Credits to the owner).
public static byte[] decode(String data)
{
int[] tbl = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
byte[] bytes = data.getBytes();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; ) {
int b = 0;
if (tbl[bytes[i]] != -1) {
b = (tbl[bytes[i]] & 0xFF) << 18;
}
// skip unknown characters
else {
i++;
continue;
}
int num = 0;
if (i + 1 < bytes.length && tbl[bytes[i+1]] != -1) {
b = b | ((tbl[bytes[i+1]] & 0xFF) << 12);
num++;
}
if (i + 2 < bytes.length && tbl[bytes[i+2]] != -1) {
b = b | ((tbl[bytes[i+2]] & 0xFF) << 6);
num++;
}
if (i + 3 < bytes.length && tbl[bytes[i+3]] != -1) {
b = b | (tbl[bytes[i+3]] & 0xFF);
num++;
}
while (num > 0) {
int c = (b & 0xFF0000) >> 16;
buffer.write((char)c);
b <<= 8;
num--;
}
i += 4;
}
return buffer.toByteArray();
}
Save it in to file using this code.
public void writeBytesToFile(String encodedString)
throws IOException {
byte[] decodedBytes = decode(encodedString);
File directory = new File("storage/emulated/0/", "Certificates");
if(!directory.exists()){
directory.mkdir();
}
Log.d("BYTS", new String(decodedBytes));
String fileFilname = certTypeStr.concat("p12file.pem");
//Toast.makeText(MyApplication.getAppContext(), fileFilname, Toast.LENGTH_SHORT).show();
File file = new File("storage/emulated/0/Certificates", fileFilname);
if(!file.exists()){
boolean createfile = file.createNewFile();
}else{
boolean deletefile = file.delete();
boolean createfile = file.createNewFile();
}
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(decodedBytes);
}
}
but seems I have no luck to make it work. Pls help me to properly convert a base64 string to a p12 file.
After many hours of trial and error for those who are trying to do the same thing. I made it work by running a Shell Command to decode the base64 string using Java ProcessBuilder. The command used :
base64 -d test.txt | base64 -d > test.p12
I don't know why the output of base64 decode differs from windows and linux commandline but this workaround is useful.
I am using bitboards to generate attack tables for rooks, bishops, and queens. During my research of magic bitboards, it seems I need to clip the edges of all of my attack tables. I store my bitboards in a long, with square a1 being the LSB and square h8 being the MSB, moving row by row. Here is an example of an attack table for a rook on square c2:
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[1, 1, 0, 1, 1, 1, 1, 1]
[0, 0, 1, 0, 0, 0, 0, 0]
My problem is that I need to make all the ones on the edge of the bitboard 0s. At first I tried &ing each attack table with a binary long representing a border clip that looks like this:
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
Now this works for most squares in the center, but for attack tables on the edges it clips it in error. SO for a rook on h8:
Initial attack table:
[1, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
Expected Result:
[0, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0]
Actual Result:
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
How should i approach this so that it only clips the end of each attack ray? I realize my bit logic is off. Thanks.
Instead of masking out the bits at the border using a constant mask, use a dynamically generated mask.
Example, the rook (♜) is on field F6, so we generate a mask where F1, F8, A6, and H6 are set. Then we use that mask to turn of those bits in your attack pattern.
0 0 0 0 0 1 0 0 8
0 0 0 0 0 0 0 0 7
1 0 0 0 0 ♜ 0 1 6
0 0 0 0 0 0 0 0 5
0 0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 2
0 0 0 0 0 1 0 0 1
A B C D E F G H
In this solution I assume that you encode the 64 squares row-wise inside a long. The square A1 is the LSB and the square H8 is the MSB. Therefore above example would be represented by 2305984846213677088L = 0x2000810000000020L = 0b0000010000000000000100000010000000000000000000000000000000000100000L
/**
* #param x 0-based index for the columns A to H (0=A_, 1=B_, ...)
* #param y 0-based index for the rows 1 to 8 (0=_1, 1=_2, ...)
*/
long rookEndpoints(int x, int y) {
long topBtm = 1L << x;
return (0b10000001L << (8 * y)) | (topBtm << (8 * 7)) | topBtm;
}
...
attackPattern &= ~rookEndpoints(x, y)
I'm new to Android and still following some tutorials. One tut is about TypedArray for storing the image information.
MainActivity.java
package com.example.materialme;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TypedArray sportsImageResources = getResources().obtainTypedArray(R.array.sports_images);
Log.d(TAG, "sportImageResources: " + sportsImageResources);
sportsImageResources.recycle();
}
}
strings.xml
<resources>
<array name="sports_images">
<item>#drawable/img_baseball</item>
<item>#drawable/img_badminton</item>
<item>#drawable/img_basketball</item>
<item>#drawable/img_bowling</item>
<item>#drawable/img_cycling</item>
<item>#drawable/img_golf</item>
<item>#drawable/img_running</item>
<item>#drawable/img_soccer</item>
<item>#drawable/img_swimming</item>
<item>#drawable/img_tabletennis</item>
<item>#drawable/img_tennis</item>
</array>
</resources>
When I see in logcat, the values of TypedArray sportsImageResources are
[3, 179, 6, 2131165272, 0, 0, 3, 178, 6, 2131165271, 0, 0, 3, 180, 6, 2131165273, 0, 0, 3, 181, 6, 2131165274, 0, 0, 3, 182, 6, 2131165275, 0, 0, 3, 183, 6, 2131165276, 0, 0, 3, 184, 6, 2131165277, 0, 0, 3, 185, 6, 2131165278, 0, 0, 3, 186, 6, 2131165279, 0, 0, 3, 187, 6, 2131165280, 0, 0, 3, 188, 6, 2131165281, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 17, 512, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 16, 250, 1, 0, 1073742848, 0, 16, 400, 1, 0, 1073742848, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 2131558747, 6, 2131558747, 1073742848, 0, 1, 2131558746, 6, 2131558746, 1073742848, 0, 28, -1, 1, 17170443, 1073742848, 0, 3, 193, 6, 2131165294, 1073742848, 0, 3, 27, 6, 0, 1073742848, 0, 18, -1, 6, 0, 1073742848, 0, 18, 0, 6, 0, 1073742848, 0, 18, 0, 6, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 18, 0, 6, 0, 1073742848, 0]
How to read this data?
May be this example will help you.
TypedArray sportsimgs = getResources().obtainTypedArray(R.array.random_imgs);
// get resource ID by index
sportsimgs .getResourceId(i, -1)
// or set you ImageView's resource to the id
mImgView1.setImageResource(sportsimgs .getResourceId(i, -1));
// recycle the array
sportsimgs .recycle();
Essentially I am making a board game using sockets. Each client connected is stored in a map .
When the user makes a move to a coordinate in the 2D Array i.e. "move 2,3", it should put the connectionID in that position.
Currently my issue is, because I have a for loop; when i use the move command, the connection ID is replaced with the last value in the loop.
public void move(int x, int y) {
for (int value : gs.returnClients().values()) {
storeArray[x][y] = value;
}
}
i.e. If i have 2 clients connected: {62029=1, 62032=2} and my board
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Let's say I want to have client 1 move to 0, 3 it should be:
[[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
But instead I get:
[[0, 0, 0, 2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Since it's overwriting the last value of the map in the for loop.
How would I make it move dependent on its client "id" from the map?
Edit
In my server i have clients.put(socket.getPort(), connectionID); and methods to return the map and id. I have a class GameService that executes command which is
switch (request.type) {
case MOVE:
int clientID = Integer.parseInt(request.params[0]);
int getX = Integer.parseInt(request.params[1]);
int getY = Integer.parseInt(request.params[2]);
game.move(clientID,getX, getY);
return game.returnBoard();
In a file Request
String[] items = line.trim().split("\\s+");
switch (items[0].toUpperCase()) {
case "MOVE":
return new Request(RequestType.MOVE, items[1], items[2], items[3]);
As far as I understand your code, you need to do your move the following way:
public void move(int client, int x, int y) {
storeArray[x][y] = client;
}
where client is one (!) of the numbers within the gs.returnClients().values()-list. If you need to take it out of that map, you need to deliver the appropriate key for that, e.g.:
public void move(int clientId, int x, int y) {
storeArray[x][y] = gs.returnClients().get(clientId);
}
I'm trying to output some very long (100000 items) array of integers to stdout.
public int myPrint(int[] A) {
System.out.println("A " + Arrays.toString(A));
}
It fails because stdout on the machine the code runs cuts the string from some point like (this is whole output, as you can see there is not 100000 items but much less):
A [-1, -1, 0, -1, 1, -1, 0, -1, 1, -1, 0, 0, -1, -1, 0, -1, 0, -1, -1, 0, 1, -1, -1, 1, -1, 1, 0, -1, 1, 1, 0, 1, -1, 0, 0, 1, -1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, -1, 1, -1, 1, 1, 0, -1, 0, 0, -1, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, 1, 1, 0, 1, 1, 0, -1, 0, -1, 1, 0, 1, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, 0, -1, 1, 0, 1, -1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, -1, -1, 1, -1, 0, 0, -1, 0, 1, 1, 0, -1, 1, 0, 0, 1, 0, -1, -1, 1, 0, 1, 1, 1, 1, -1, 1, -1, 0, 1, 0, -1, 0, 0, 0, 1, 0, -1, 0, -1, -1, 0, 1, -1, -1, -1, 1, 1, -1, 0, -1, -1, 0, 0, 1, 1, 0, 1, 0, 1, 1, -1, 1, 0, 0, 0, -1, 0, -1, 0, 1, 1, 0, 0, 1, -1, -1, 1, 0, 1, 0, 0, 1, 0, 1, 1, -1, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, -1, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, -1, 0, 0, -1, 1, 0, 1, -1, 1, -1, -1, 0, 1, 0, -1, 1, -1, 1, 1, -1, 1, 0, 1, 1, 1, -1, 0, 1, -1, 0, 1, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 1, 1, 1, -1, 1, 0, -1, -1, 0, 0, -1, -1, 1, -1, 1, 0, 1, -1, 0, 1, 0, 0, 0, -1, -1, -1, -1, 1, -1, 1, -1, 0, 0, -1, 1, 1, 1, 0, -1, -1, -1, 1, 1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, 1, 0, -1, -1, 1, 1, -1, 0, 1, 0, -1, 0, -1, -1, 1, -1, 1, 1, 0, -1, -1, 1, 1, -1, -1, 0, 1, -1, 1, -1, -1, -1, 0, 1, 0, -1, -1, 0, -1, 1, 0, 1, 1, 1, -1, 0, 1, -1, -1, -1, 0, 1, 1, -1, -1, 1, -1, -1, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0, 0, 1, 1, 0, 0, 1, -1, 0, 1, 0, -1, 1, 0, 0, -1, 0, 1, -1, 0, -1, -1, 0, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 0, -1, 1, 0, -1, 1, -1, -1, -1, -1, 0, 0, 0, 0, -1, 0, 1, -1, 1, 0, 1, 0, 0, -1, -1, -1, -1, 1, 1, 1, 1, 0, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 0, 0, 0, 0, -1, -1, 0, 1, 0, -1, -1, -1, 1, 0, 0, 0, 1, 1, -1, 0, 0, 1, -1, 0, -1, 0, 1, 0, 0, 0, 1, 1, -1, -1, 0, -1, -1, 1, -1, 0, -1, 1, 1, 1, 1, 0, 0, -1, 0, 1, 0, -1, -1, -1, 1, -1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 1, 1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 0, -1, 1, -1, 1, 0, -1, -1, 0, 1, 0, -1, 0, 1, 0, -1
The code is remotely executed and I don't have option to change stdout formatting/buffer size etc. on the machine so it must be done inside the method.
Maybe I should split the string into sub strings?
Do not use Arrays.toString here. But output immediate values.
Maybe with extra flushing, as done with a println.
public int myPrint(int[] A) {
System.out.print("A [");
for (int i = 0; i < A.length; ++i) {
if (i % 25 == 0) {
System.out.println(); // Or flush()
}
if (i != 0) {
System.out.print(", ");
}
System.out.print(A[i];
}
System.out.println("]");
}
int width = 80;
int c = 0;
for(int i: A){
String item = i + " ";
c += item.length();
System.out.print(c);
if(c>width){
System.out.println();
c=0;
}
}
Only prints 80 or so characters to the terminal before adding a new line.