Find single line comments in byte array - java

Is it possible to find instances of // in a line read from a file into a byte array and then "snip" from // to the end of the line out? I'm trying
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[8 * 1024];
int read;
while ((read = fis.read(buffer)) != -1)
{
for (int i = 0; i < read; i++)
{
if (buffer[i] == '//')
{
buffer = buffer[0:i];
}
}
}
but I'm getting Invalid character constant at if (buffer[i] == '//') on the '//' part. Am I doing something wrong, or is this just not possible?

Old-school solution
for (int i = 0; i < read-1; i++)
{
(if (buffer[i] == '/') && (buffer[i+1]== '/'))
{
buffer = buffer[0:i];
}
}

' and ' denote one character. Since // are two characters this does not work. One has to differentiate between a character and a string. Thus you have to individually check both positions in the byte array to confirm there are two successive /s.

Related

Decryption only yields one correct line after encrypting line by line using RC4 algorithm

I have to encrypt a file line by line using the RC4 algorithm.
Encrypting the whole file and decrypting the whole file yields the original which is fine.
When I attempt to read the file one line at a time,encrypt it and then write the encrypted line to file, decryption of the resulting file yields just one correct line which is the first line of the original file.
I have tried to read the file and feed it to rc4 routine using a byte array whose size is a multiple of the key length but the results were the same. Here is my attempt:
try
{
BufferedReader br = new BufferedReader((new FileReader(fileToEncrypt)));
FileOutputStream fos = new FileOutputStream("C:\\Users\\nikaselo\\Documents\\Encryption\\encrypted.csv", true);
File file = new File("C:\\Users\\nikaselo\\Documents\\Encryption\\encrypted.csv");
// encrypt
while ((line = br.readLine()) != null)
{
byte [] encrypt = fed.RC4(line.getBytes(), pwd);
if (encrypt != null) dos.write(encrypt);
fos.flush();
}
fos.close();
// test decrypt
FileInputStream fis = null;
fis = new FileInputStream(file);
byte[] input = new byte[512];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1)
{
byte [] de= fed.RC4(input, pwd);
String result = new String(de);
System.out.println(result);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
and here is my RC4 function
public byte [] RC4 (byte [] Str, String Pwd) throws Exception
{
int[] Sbox = new int [256] ;
int A, B,c,Tmp;;
byte [] Key = {};
byte [] ByteArray = {};
//KEY
if ((Pwd.length() == 0 || Str.length == 0))
{
byte [] arr = {};
return arr;
}
if(Pwd.length() > 256)
{
Key = Pwd.substring(0, 256).getBytes();
}
else
{
Key = Pwd.getBytes();
}
//String
for( A = 0 ; A <= 255; A++ )
{
Sbox[A] = A;
}
A = B = c= 0;
for (A = 0; A <= 255; A++)
{
B = (B + Sbox[A] + Key[A % Pwd.length()]) % 256;
Tmp = Sbox[A];
Sbox[A] = Sbox[B];
Sbox[B] = Tmp;
}
A = B = c= 0;
ByteArray = Str;
for (A = 0; A <= Str.length -1 ; A++)
{
B = (B + 1) % 256;
c = (c + Sbox[B]) % 256;
Tmp = Sbox[B];
Sbox[B] = Sbox[c];
Sbox[c] = Tmp;
ByteArray[A] = (byte) (ByteArray[A] ^ (Sbox[(Sbox[B] + Sbox[c]) % 256]));
}
return ByteArray;
}
Running this gives me one clean line and the rest is just unreadable.
You are encrypting line by line, but you are trying to decrypt in 512 bytes blocks.
Your options, as I see it are:
Encrypt and decrypt in fixed sized blocks
Pad each line out to 512 bytes (and split lines that are longer than 512 bytes)
Introduce a delimiter. This will be tricky because potentially any delimiter could appear in the cipher text, so you should base64 encode each encrypted line and separate them with line feeds.
Probably 1 is the easiest (and the one used in real encryption), but if you have to do it line by line, I would go with 3 even though this introduces a vulnerability, but it's RC4 which is no longer considered secure anyway.

HTTP manual Client not writing to disk properly JAVA

I am trying to build a manual HTTP client (using sockets) along with a cache and I cant seem to figure out why the files are not saving to disk properly. It works pretty good for HTML files, but cant seem to work for other files types that re not text based like .gif. Could anyone tell me why? I am quite new to HTTP protocol and Socket programming in general.
The loop to grab the response.
InputStream inputStream = socket.getInputStream();
PrintWriter outputStream = new PrintWriter(socket.getOutputStream());
ArrayList<Byte> dataIn = new ArrayList<Byte>();
ArrayList<String> stringData = new ArrayList<String>();
//Indices to show the location of certain lines in arrayList
int blankIndex = 8;
int lastModIndex = 0;
int byteBlankIndex = 0;
try
{
//Get last modified date
long lastMod = getLastModified(url);
Date d = new Date(lastMod);
//Construct the get request
outputStream.print("GET "+ "/" + pathName + " HTTP/1.1\r\n");
outputStream.print("If-Modified-Since: " + ft.format(d)+ "\r\n");
outputStream.print("Host: " + hostString+"\r\n");
outputStream.print("\r\n");
outputStream.flush();
//Booleans to prevent duplicates, only need first occurrences of key strings
boolean blankDetected = false;
boolean lastModDetected = false;
//Keep track of current index
int count = 0;
int byteCount = 0;
//While loop to read response
String buff = "";
byte t;
while ( (t = (byte) inputStream.read()) != -1)
{
dataIn.add(t);
//Check for key lines
char x = (char) t;
buff = buff + x;
//For the first blank line (signaling the end of the header)
if(x == '\n')
{
stringData.add(buff);
if(buff.equals("\r\n") && !blankDetected)
{
blankDetected = true;
blankIndex = count;
byteBlankIndex = byteCount + 2;
}
//For the last modified line
if(buff.contains("Last-Modified:") && !lastModDetected)
{
lastModDetected = true;
lastModIndex = count;
}
buff = "";
count++;
}
//Increment count
byteCount++;
}
}
The the code to parse through response and write file to disk.
String catalogKey = hostString+ "/" + pathName;
//Get the directory sequence to make
String directoryPath = catalogKey.substring(0, catalogKey.lastIndexOf("/") + 1);
//Make the directory sequence if possible, ignore the boolean value that results
boolean ignoreThisBooleanVal = new File(directoryPath).mkdirs();
//Setup output file, and then write the contents of dataIn (excluding header) to the file
PrintWriter output = new PrintWriter(new FileWriter(new File(catalogKey)),true);
for(int i = byteBlankIndex + 1 ; i < dataIn.size(); i++)
{
output.print(new String(new byte[]{ (byte)dataIn.get(i)}, StandardCharsets.UTF_8));
}
output.close();
byte t;
while ( (t = (byte) inputStream.read()) != -1)
The problem is here. It should read:
int t;
while ( (t = inputStream.read()) != -1)
{
byte b = (byte)t;
// use b from now on in the loop.
The issue is that a byte of 0xff in the input will be returned to the int as 0xff, but to the byte as -1, so you are unable to distinguish it from end of stream.
And you should use a FileOutputStream, not a FileWriter, and you should not accumulate potentially binary data into a String or StringBuffer or anything to do with char. As soon as you've got to the end of the header you should open a FileOutputStream and just start copying bytes. Use buffered streams to make all this more efficient.
Not much point in any of these given that HttpURLConnection already exists.

How to read whole file with read(char[] cbuf, int off, int len)

I've got this soure:
public static void inBufferBooks() throws IOException
{
Reader inStreamBooks = null;
BufferedReader bufferIn = null;
try
{
inStreamBooks = new FileReader("Files/BufferBook.txt");
bufferIn = new BufferedReader(inStreamBooks);
char text[] = new char[10];
int i = -1;
while ((i = inStreamBooks.read(text, 0, 10)) != -1)
{
System.out.print(text);
}
When I read file at the end of the text console printing chars who's fill last array.
How can I read whole text from the file without redundant chars from last array?
How can I read whole text from the file without redundant chars from last array?
Use the value read returns to you to determine how many characters in the array are still valid. From the documentation:
Returns:
The number of characters read, or -1 if the end of the stream has been reached
You need to remember how may characters you read and only print that many.
for (int len; ((len = inStreamBooks.read(text, 0, text.length)) != -1; ) {
System.out.print(new String(text, 0, len));
}
To resolve the problem I change my while cycle like this:
while((i = bufferText.read(text, 0, text.length)) != -1){
if(text.length == i){
System.out.print(text);
}else if (text.length != i){
System.out.print(Arrays.copyOfRange(text, 0, i));
}
Thanks everyone for the help.

Read line as array of bytes without default encoding

How to read in the most efficient way one line from a file (finished by \n, or \r, or both) as an array of bytes withouth going through String (if I read line into String, the default encoding is applied and I don't want to have this step).
I don't think you can do this without doing it manually. But to save you time, I'll write the code for you:
public static byte[] firstLine(InputStream in) {
byte[] buffer = new byte[1024]; // arbitrary number
int idx = 0;
byte b;
while ((b = in.read()) != 0x0d || b != 0x0a) { // those codes are CR and LF
if (idx >= buffer.length)
buffer = Arrays.copyOf(buffer, buffer.length * 2);
buffer[idx] = b;
return Arrays.copyOf(buffer, idx);
}

Java - Want to parse through eof. Code only parses once

My code below only parses through the data file once. I'm trying to get it to parse through the whole file. Every time it finds a marker, parse the data and append it to the output file. Currently it successfully parses the data once and then stops. Can't figure out how to keep it looping until eof. The data is 4 byte aligned and is in a input binary file.
private static void startParse(File inFile) throws IOException {
boolean markerFound = false;
for (int offset = 0; !markerFound && offset < 4; offset++){
DataInputStream dis = new DataInputStream(new FileInputStream(inFile));
for (int i = 0; i < offset; i++){
dis.read();
}
try {
int integer;
long l;
while((l = (integer = dis.readInt())) != MARKER) {
//Don't do anything
}
markerFound = true;
for (int i = 0; i < 11; i++){
dis.read();
}
// ********************** data **********************
byte[] data = new byte[1016];
for(int i = 0; i < 1016; i++){
data[i] = (byte) dis.read();
}
for (int i = 0; i < 4; i++){
dis.read();
}
// ***************** output data ********************
if (checksumCheck(checksum) && fecfCheck(fecf)){
FileOutputStream output = new FileOutputStream("ParsedData", true);
try{
output.write(data);
}
finally{
output.close();
}
}
}
catch (EOFException eof) {
}
dis.close();
}
}
markerFound = true;
This line is not inside a conditional and will be executed in any occurrence of the loop.
Which will of course shut down your loop because:
for (int offset = 0; !markerFound && offset < 4; offset++)
First thing
You are opening the file inside your for, so, the reading always will start at the beginning of the file. Open it before the first for.
Second
Because of the test !markerFound && offset < 4, your loop will occur max 4 times.
Third
This code not make sense to me:
for (int i = 0; i < offset; i++){
dis.read();
}
Because the offset, in the first iteration, is 0, in the next will be 1, and so on. And that loop is not necessary, you are using another loop to read bytes until reach the MARKER.
Fourth
If your file has "records" with fixed lenghts and the markers occurs on predictable positionings, use the DataInputStream skipBytes method to go forward to next marker.
As I'd posted in an earlier answer to your question Java, need a while loop to reach eof. i.e.while !eof, keep parsing I'd like to state again that DataInputStream.read() (unlike other readXxX() methods) does not throw EOFExcepion.
From the JavaDocs: (DataInputStream inherits read() from FilterInputStream)
If no byte is available because the end of the stream has been reached, the value -1 is returned.
So, to correctly check for EOF, usually read(byte[]) is used in a while loop as follows:
int read = 0;
byte[] b = new byte[1024];
while ((read = dis.read(b)) != -1) { // returns numOfBytesRead or -1 at EOF
// fos = FileOutputStream
fos.write(b, 0, read); // (byte[], offset, numOfBytesToWrite)
}
Answer
Now, getting back to your current question; since, you haven't shared your binary file format it's difficult to suggest a better way to parse it. So, from the limited understanding of the way your nested loops are parsing your file currently; you need another while loop (as reasoned above) to read/parse and copy your "data" till you reach EOF once you've found the marker.
markerFound = true;
for (int i = 0; i < 11; i++){ // move this loop inside while IF
dis.read(); // these 11 bytes need to be skipped every time
}
// Open the file just ONCE (outside the loop)
FileOutputStream output = new FileOutputStream("ParsedData", true);
// ********************** data **********************
int read = 0;
byte[] data = new byte[1016]; // set byte buffer size
while ((read = dis.read(data)) != -1) { // read and check for EOF
// ***************** output data ********************
if (checksumCheck(checksum) && fecfCheck(fecf)) { // if checksum is valid
output.write(data, 0, read); // write the number of bytes read before
}
// SKIP four bytes
for (int i = 0; i < 4; i++) { // or, dis.skipBytes(4); instead of the loop
dis.read();
}
}
// Close the file AFTER input stream reaches EOF
output.close(); // i.e. all the data has been written

Categories