What are the mask values for decoding websocket frames? - java

I know that ENCODED are the bytes array, but what is MASK, what are his values?
var DECODED = "";
for (var i = 0; i < ENCODED.length; i++) {
DECODED[i] = ENCODED[i] ^ MASK[i % 4];
}
I've found this example on the web, the question is how can I know what are the MASK values?
any hint or links please? but in the google examples I find only this type of code, but I wish to see explicitly the MASK values, any help please
pstream = new BufferedWriter(new OutputStreamWriter(csocket.getOutputStream(), StandardCharsets.UTF_8));
char[] buff = new char[4];
pstream.read(buf);
//now buf have that masks?

Right above that code snippet it says:
If the MASK bit was set (and it should be, for client-to-server messages), read the next 4 octets (32 bits); this is the masking key.
You can find the MASK bit in the data frame format description.
So the pseudocode could be extended to
var LEN = decodeLength(buffer);
var MASK = buffer.read(4);
var ENCODED = buffer.read(LEN);
var DECODED = new Buffer(LEN);
for (var i = 0; i < ENCODED.length; i++) {
DECODED[i] = ENCODED[i] ^ MASK[i % 4];
}

Related

Is this encryption function reversible?

I'm currently working on a small challenge, trying to figure out how an unnamed encryption algorithm works. The original algorithm looks like this:
public final String a(byte[] original)
{
this.a = original.length;
byte[] solution = new byte[8];
int i = 0;
int base = 13;
for (int si = 0; si < 8; si++)
{
for (int oi = 0; oi < a; oi++)
{
byte current = original[oi];
solution[i] = ((byte)(solution[i] + (current ^ base)));
base = (base ^ i) + solution[i];
i = (i + 1) % 8;
}
}
char[] result = new char[8];
for (int n = 0; n < 8; n++) {
result[n] = ((char)((solution[n] & 0x3F) + 48));
}
return String.valueOf(result);
}
So every string that gets passed to this function as a byte[] array will be encoded into a 8-char somewhat cryptic text. I've found out other things about this:
The encoded characters in the char[] result always have literals with values between 48 and 111 (0x3F + 48).
When decoding, the first step would be subtracting 48 and then undo the & operation. Since 0x3F equals the binary representation 111111, the value of the original byte is one of 4 possibilities:
00xxxxxx: the missing 2 bits were both zero.
01xxxxxx: the lower addressed bit of both was one.
10xxxxxx: the higher addressed bit of both was one.
11xxxxxx: both of them were one.
Meaning, it could be one of four characters. I initially thought about reversing the algorithm, but I'm asking you if this is even possible for this kind of algorithm. I tried it and came this far:
public static String b(String encrypted) {
byte[][] matrix = new byte[4][20];
byte[] word = encrypted.getBytes();
for(int i = 0; i < 4; i++) {
for(int j = 0; j < word.length; j++) {
byte tmp = (byte)(word[i] - 48);
matrix[i][j] = (byte)(tmp + i);
}
}
}
I currently subtract 48 and insert all 4 possibilities into a 2D-array. But im stuck solving the nested for loop, especially the variables i and base are hard to find out. The only information I have is the encrypted word and the fact that the original word was 20 literals long at MAX (Hence the [4][20] dimensions).
The encryption doesn't look familiar to me, which leaves me no options to look for the name of this algorithm.
If it is possible to reverse this algorithm, what would my next step be?
No, that obviously can't be reversible in the general case.
There are effectively 40 bits of information in the output (eight bytes, at 5 bits each -- & 0x1F limits each one to five bits). This means that there are only 240 possible outputs; there are far more possible inputs than that.
If there are some constraints on the input -- for instance, if its length is known to be short -- it might be possible to make some inferences about that. However, you haven't stated any constraints, so…

How to merge 2 binarybyte array in java [duplicate]

This question already has answers here:
How to combine two byte arrays [duplicate]
(7 answers)
Closed 8 years ago.
I have 2 byte array like this:
byte a[i]=1;
byte b[i]=0;
I want to merge it so that the output result becomes "10". I try to use arraycopy and make new output
byte[] output=a.length+b.length;
but it still doesn't work like my expectation. Anybody knows how to solve it?
Try this.
byte[] first = getFirstBytes();
byte[] second = getSecondBytes();
List<Byte> listOfBytes = new ArrayList<Byte>(Arrays.<Byte>asList(first));
listOfBytes.addAll(Arrays.<Byte>asList(second));
byte[] combinedByte = listOfBytes.toArray(new byte[listOfBytes.size()]);
Try this
byte[] first = {1,2,4,56,6};
byte[] second = {4,5,7,9,2};
byte[] merged = new byte[first.length+second.length];
System.arraycopy(first,0,merged,0,first.length);
System.arraycopy(second,0,merged,first.length,second.length);
for(int i=0; i<merged.length;i++)
{
System.out.println(merged[i]);
}
Try this.
byte a[i] = 1;
byte b[i] = 0;
byte[] output = new byte[a.length + b.length];
for(int i = 0 ; i < output.length ; ++i)
{
if(i < a.length) output[i] = a[i];
else output[i] = b[i - a.length];
}

Wireshark hex dump analyzer possible to do in Java?

I have a pcap file and I can view the hex and human-readable string equivalent of the hexdump using wireshark. However, I want to do the same but in Java. Here is a screenshot from Wireshark application.
Taking the highlighted string, this is what i've come but the output is not what I've expect. Can someone help me? Thank you very much
String hex = "a106020110020138";
byte[] bts = new byte[hex.length() / 2];
for (int i = 0; i < bts.length; i++) {
bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
String c = new String(bts, StandardCharsets.US_ASCII);
System.out.println(c);
This is the output:
Java uses UTF-16 for characters, in what byte order i forgot, meaning you need to use two bytes per character.
If you want the output to look exactly like Wireshark's, you can do by reading each group of two hex digits, and keeping that ones that correspond to printable ASCII characters:
public class Pcap {
public static void main(String[] args) {
String hex = "701c2f676c08a106020110020138";
int n = hex.length();
char[] cs = new char[n / 2];
for (int i = 0; i < n; i+=2)
cs[i/2] = (char) Integer.parseInt(hex.substring(i, i+2), 16);
for (int i = 0; i < cs.length; i++)
if (cs[i] < ' ' || cs[i] > '~') // printable ASCII
cs[i] = '.';
System.out.println(new String(cs));
}
}
which outputs
p./gl........8
However, my guess is that you're better off using a library that can parse pcaps (I mentioned one earlier, it looks like http://jpcap.sourceforge.net might also work), since just getting that hex string in the first place required opening Wireshark. You can write the code yourself to pull those values from the (binary) pcap file, but projects already exist to do that.

Spectral analysis using FFT, fundamental frequency derivation

I need to perform spectral analysis of a simple wav file.
The things I have already done :
Read file into byte array :
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = audioStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
fileByteArray = baos.toByteArray();
Then I transform it to the real values (doubles).
I've got sample values stored in double[] array.
How can I make FFT of those samples + estimate fundamental frequency?
Using JTranforms library I tried something like this :
DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
double[] x = reader.getSpectrum().getYvalues();
double[] frequencyArray = new double[x.lenght/2];
double[] amplitudeArray = new double[x.lenght/2];
fft.realForward(x);
int i=0;
for (int j = 0; j < x.length-2; j += 2) {
i++;
this.frequencyArray[i] = i;
this.amplitudeArray[i] = Math.sqrt(Math.pow(doub[j],2) + Math.pow(doub[j + 1],2));
}
Is it correct?
All suggestions are appreciated ;)
You should use autocorrelation which can be computed efficiently with FFT:
DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
DoubleFFT_1D ifft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
fft.realForward(x);
for (int i = 0; i < x.length/2; i++) {
x[2*i] = Math.sqrt(Math.pow(x[2*i],2) + Math.pow(x[2*i+1],2));
x[2*i+1] = 0;
}
ifft.realInverse(x);
for (int i = 1; i < x.length; i++)
x[i] /= x[0];
x[0] = 1.0;
This code gives you a list of values for which:
x[i]: corelation with i shifts
So, for example if you have a high value (close to 1) for x[n], that means you have a fundemental signal period that is: n*(1000/sampleRateHz) msecs. This is equivalent to a frequency of: sampleRateHz/(1000*n)
The values in the frequency array need to be related to the sample rate and the length of the FFT.
You will still need to solve the problem of determining the fundamental frequency versus the peak frequencies. For that, you may want to use a pitch detection/estimation algorithm, of which there are many (look for research papers on the topic).

How to convert image to Boolean Array in Java (Android)?

I'm trying to store a 32 x 32 Boolean array in a 32 x 32 black and white image (either bitmap or PNG), to then be mapped to a Boolean[32][32] array with black pixels being true and white being false.
This is to store frames of animation to display on a virtual 32 x 32 display. Here's what I have so far below.
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.raw.f1);
bmp.compress(Bitmap.CompressFormat.PNG, 100, o_stream);
byte[] byteArray = o_stream.toByteArray();
What do I do with byteArray to make it a Boolean[32][32] array or am I going about this all wrong in the first place?
While I never did anything with images (so I don't know if this is anything close to what one should do to get the black-and-white of a pic), I suppose you need a rule to decide whether a pixel is closer to black or closer to white. But I'm curious, how can a byte represent a color? Even if it's RGB, you need at least three bytes, don't you?
if(src!= null){
ByteArrayOutputStream os=new ByteArrayOutputStream();
src.compress(android.graphics.Bitmap.CompressFormat.PNG, 100,(OutputStream) os);
byte[] byteArray = os.toByteArray();
//Log.d("byte=",""+byteArray.length);//returns length.
//str = Base64.encodeToString(byteArray,Base64.DEFAULT);//returns string
}
where src is the bitmap....
If you just want to encode an array of Booleans into a bitmap to save storage space, why use an image? That's a lot of extra overhead. Why not just create a bitmap yourself, like this:
Boolean[][] booleanArray = ... // this is your Boolean array
int[] bits = new int[32]; // One int holds 32 bits
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
if (booleanArray[i][j]) {
// Set bit at the corresponding position in the bits array
bits[i] |= 1 << j;
}
}
}
// Now you have the data in a int array which you can write to a file
// using DataOutputStream. The file would contain 128 bytes.
// To recreate the Boolean[32][32] from the int array, do this:
Boolean[][] booleanArray = new Boolean[32][32];
int[] bits = ... // This is the data you read from the file using DataInputStream
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
if ((bits[i] & (1 << j)) != 0) {
// Set corresponding Boolean
booleanArray[i][j] = true;
}
}
}

Categories