3import java.io.ByteArrayOutputStream;
4import java.io.IOException;
5
6public class PacketOutputStream extends ByteArrayOutputStream { 7 8 private byte[] byteBuffer = new byte[1]; 9 private byte[] shortBuffer = new byte[2];10 private byte[] intBuffer = new byte[4];11 private byte[] longBuffer = new byte[8];1213 public synchronized void putByte(byte val) throws IOException {14 byteBuffer[0] = (byte) (val >>> 8);15 write(byteBuffer);16 }1718 public synchronized void putBoolean(boolean val) throws IOException {19 byteBuffer[0] = (byte) (val ? 1 : 0);20 write(byteBuffer);21 }2223 public synchronized void putChar(char val) throws IOException {24 shortBuffer[1] = (byte) (val >>> 8);25 shortBuffer[0] = (byte) (val);26 write(shortBuffer);27 }2829 public synchronized void putShort(short val) throws IOException {30 shortBuffer[1] = (byte) (val >>> 8);31 shortBuffer[0] = (byte) (val);32 write(shortBuffer);33 }3435 public synchronized void putInt(int val) throws IOException {36 intBuffer[3] = (byte) (val >>> 24);37 intBuffer[2] = (byte) (val >>> 16);38 intBuffer[1] = (byte) (val >>> 8);39 intBuffer[0] = (byte) (val);40 write(intBuffer);41 }4243 public synchronized void putFloat(float val) throws IOException {44 putInt(Float.floatToIntBits(val));45 }4647 public synchronized void putLong(long val) throws IOException {48 longBuffer[7] = (byte) (val >>> 56);49 longBuffer[6] = (byte) (val >>> 48);50 longBuffer[5] = (byte) (val >>> 40);51 longBuffer[4] = (byte) (val >>> 32);52 longBuffer[3] = (byte) (val >>> 24);53 longBuffer[2] = (byte) (val >>> 16);54 longBuffer[1] = (byte) (val >>> 8);55 longBuffer[0] = (byte) (val);56 write(longBuffer);57 }5859 public synchronized void putDouble(double val) throws IOException {60 putLong(Double.doubleToLongBits(val));61 }6263}
3import java.io.ByteArrayInputStream;
4import java.io.IOException;
5
6public class PacketInputStream extends ByteArrayInputStream { 7 8 private byte[] tmpBuffer = new byte[8]; 910 public PacketInputStream(byte[] buf) {11 super(buf);12 }1314 public PacketInputStream(byte[] buf, int offset, int length) {15 super(buf, offset, length);16 }1718 public synchronized byte readByte() throws IOException {19 read(tmpBuffer, 0, 1);20 return tmpBuffer[0];21 }2223 public synchronized boolean readBoolean() throws IOException {24 read(tmpBuffer, 0, 1);25 return (tmpBuffer[0] == 0 ? true : false);26 }2728 public synchronized char readChar() throws IOException {29 read(tmpBuffer, 0, 2);3031 return (char) ((tmpBuffer[0] & 0xFF) + (tmpBuffer[1] << 8));32 }3334 public synchronized short readShort() throws IOException {35 read(tmpBuffer, 0, 2);3637 return (short) ((tmpBuffer[0] & 0xFF) + (tmpBuffer[1] << 8));38 }3940 public synchronized int readInt() throws IOException {41 read(tmpBuffer, 0, 4);4243 return ((tmpBuffer[0] & 0xFF)) + ((tmpBuffer[1] & 0xFF) << 8) + ((tmpBuffer[2] & 0xFF) << 16)44 + ((tmpBuffer[3]) << 24);45 }4647 public synchronized float readFloat() throws IOException {48 return Float.intBitsToFloat(readInt());49 }5051 public synchronized long readLong() throws IOException {52 read(tmpBuffer, 0, 8);5354 return ((tmpBuffer[0] & 0xFFL)) + ((tmpBuffer[1] & 0xFFL) << 8) + ((tmpBuffer[2] & 0xFFL) << 16)55 + ((tmpBuffer[3] & 0xFFL) << 24) + ((tmpBuffer[4] & 0xFFL) << 32) + ((tmpBuffer[5] & 0xFFL) << 40)56 + ((tmpBuffer[6] & 0xFFL) << 48) + (((long) tmpBuffer[7]) << 56);57 }5859 public synchronized double readDouble(double val) throws IOException {60 return Double.doubleToLongBits(readLong());61 }6263}
1package javaw2;
2
3public class MsgLockPasswordRequest extends MsgHeader {4 final public byte[] password = new byte[16];5 public int change;6}
7import java.util.ArrayList;
8import java.util.List;
9
10public class MsgHeader {1112 public short size_;13 public byte key_;14 public byte hash_;15 public short code_;16 public short index_;17 public int timestamp_;1819 public void readObject(PacketInputStream aInputStream)20 throws IOException, IllegalArgumentException, IllegalAccessException {21 List<Class> classes = new ArrayList<>();22 Class current = this.getClass();23 if (current.getSuperclass() != null) {24 classes.add(current.getSuperclass());25 }26 classes.add(current);27 for (Class c : classes) {28 for (Field f : c.getDeclaredFields()) {29 if (f.getType() == byte.class) {30 f.setByte(this, aInputStream.readByte());31 } else if (f.getType() == short.class) {32 f.setShort(this, aInputStream.readShort());33 } else if (f.getType() == int.class) {34 f.setInt(this, aInputStream.readInt());35 } else if (f.getType().isArray()) {36 if (f.getType().getComponentType() == byte.class) {37 byte[] _arr = (byte[]) f.get(this);38 aInputStream.read(_arr, 0, Array.getLength(_arr));39 }40 }41 }42 }43 }4445 public void writeObject(PacketOutputStream aOutputStream)46 throws IOException, IllegalArgumentException, IllegalAccessException {47 List<Class> classes = new ArrayList<>();48 Class current = this.getClass();49 if (current.getSuperclass() != null) {50 classes.add(current.getSuperclass());51 }52 classes.add(current);53 for (Class c : classes) {54 for (Field f : c.getDeclaredFields()) {55 if (f.getType() == byte.class) {56 aOutputStream.putByte((byte) f.get(this));57 } else if (f.getType() == short.class) {58 aOutputStream.putShort((short) f.get(this));59 } else if (f.getType() == int.class) {60 aOutputStream.putInt((int) f.get(this));61 } else if (f.getType().isArray()) {62 if (f.getType().getComponentType() == byte.class) {63 aOutputStream.write((byte[]) f.get(this));64 }65 }66 }67 }68 }69}
11import java.io.ObjectInputStream;
12import java.io.ObjectOutputStream;
13
14public class Main { 15 16 public static byte[] keys = new byte[512]; 17 public static long sizeEncryptedFile; 18 public static byte[] encryptedFileRaw; 19 public static List<MsgHeader> encryptedPackets = new ArrayList<MsgHeader>(); 20 public static long sizeDecryptedFile; 21 public static byte[] decryptedFileRaw; 22 public static List<MsgHeader> decryptedPackets = new ArrayList<MsgHeader>(); 23 24 public static void main(String[] args) { 25 if (args.length < 4) { 26 System.exit(-1); 27 } 28 if (readKeys(args[0]) == false) { 29 System.exit(-2); 30 } 31 if ((sizeEncryptedFile = readData(args[2], true, encryptedPackets)) == 0) { 32 System.exit(-3); 33 } 34 if ((sizeDecryptedFile = readData(args[3], false, decryptedPackets)) == 0) { 35 System.exit(-4); 36 } 37 if (args[1].equals("enc")) { 38 encrypt(); 39 writeData("./encoded.bin", decryptedFileRaw); 40 } 41 if (args[1].equals("dec")) { 42 decrypt(); 43 writeData("./decoded.bin", encryptedFileRaw); 44 } 45 int diff = 0; 46 for (int i = 0; i < sizeEncryptedFile; i++) { 47 diff += (encryptedFileRaw[i] != decryptedFileRaw[i] ? 1 : 0); 48 } 49 50 System.out.printf("%d differences\n", diff); 51 52 System.exit(diff); 53 } 54 55 public static boolean readKeys(String filePath) { 56 try { 57 FileInputStream file = new FileInputStream(filePath); 58 file.read(keys); 59 file.close(); 60 } catch (IOException e) { 61 return false; 62 } 63 return true; 64 } 65 66 public static void preparePackets(byte[] buffer, int size, List<MsgHeader> packets) { 67 68 try { 69 PacketInputStream bis = new PacketInputStream(buffer); 70 int i = 0; 71 while (i < size) { 72 bis.mark(i); 73 MsgHeader packet = new MsgHeader(); 74 packet.readObject(bis); 75 if (packet.size_ != 12) { 76 packet = new MsgLockPasswordRequest(); 77 bis.reset(); 78 packet.readObject(bis); 79 } 80 packets.add(packet); 81 i += packet.size_; 82 } 83 } catch (Exception e) { 84 System.out.println(e); 85 } 86 } 87 88 public static void writeData(String filePath, byte[] buffer) { 89 try { 90 File file = new File(filePath); 91 FileOutputStream fileStream = new FileOutputStream(file); 92 fileStream.write(buffer); 93 fileStream.close(); 94 } catch (Exception e) { 95 } 96 } 97 98 public static long readData(String filePath, boolean encrypted, List<MsgHeader> packets) { 99 int size = 0;100 try {101 File file = new File(filePath);102 FileInputStream fileStream = new FileInputStream(file);103 size = (int) file.length();104 if (encrypted) {105 encryptedFileRaw = new byte[size];106 fileStream.read(encryptedFileRaw);107 fileStream.close();108 preparePackets(encryptedFileRaw, size, packets);109 } else {110 decryptedFileRaw = new byte[size];111 fileStream.read(decryptedFileRaw);112 fileStream.close();113 preparePackets(decryptedFileRaw, size, packets);114 }115 } catch (Exception e) {116 System.out.println(e);117 }118 return (long) size;119 }120121 public static void decrypt() {122 int offset = 0;123 for (MsgHeader packet : encryptedPackets) {124 try {125 PacketOutputStream pos = new PacketOutputStream();126 packet.writeObject(pos);127 byte[] buffer = pos.toByteArray();128 pos.flush();129 int key = (int) (keys[(int) (packet.key_ & 0xFF) << 1] & 0xFF);130 short j = 4;131 do {132 int mappedKey = (int) (keys[((key % 256) << 1) + 1] & 0xFF);133 switch (j & 3) {134 case 0:135 buffer[j] = (byte) (buffer[j] - (byte) (mappedKey << 1));136 break;137 case 1:138 buffer[j] = (byte) (buffer[j] + (byte) ((int) (mappedKey >>> 3)));139 break;140 case 2:141 buffer[j] = (byte) (buffer[j] - (byte) (mappedKey << 2));142 break;143 case 3:144 buffer[j] = (byte) (buffer[j] + (byte) ((int) (mappedKey >>> 5)));145 break;146 }147 encryptedFileRaw[offset + j] = buffer[j];148 j++;149 key++;150 } while (j < packet.size_);151 offset += j;152 } catch (Exception e) {153 }154 }155 }156157 public static void encrypt() {158 int offset = 0;159 for (MsgHeader packet : decryptedPackets) {160 try {161 PacketOutputStream pos = new PacketOutputStream();162 packet.writeObject(pos);163 byte[] buffer = pos.toByteArray();164 pos.flush();165 int key = (byte) keys[packet.key_ << 1];166 short j = 4;167 do {168 int mappedKey = keys[((key % 256) << 1) + 1];169 switch (j & 3) {170 case 0:171 buffer[j] = (byte) (buffer[j] + (byte) (mappedKey << 1));172 break;173 case 1:174 buffer[j] = (byte) (buffer[j] - (byte) ((int) (mappedKey >>> 3)));175 break;176 case 2:177 buffer[j] = (byte) (buffer[j] + (byte) (mappedKey << 2));178 break;179 case 3:180 buffer[j] = (byte) (buffer[j] - (byte) ((int) (mappedKey >>> 5)));181 break;182 }183 decryptedFileRaw[offset + j] = buffer[j];184 j++;185 key++;186 } while (j < packet.size_);187 offset += j;188 } catch (Exception e) {189 }190 }191 }192}
This class does not have any documentation.
Consider adding a documentation comment to explain its use.
While it may seem like the functionality of a class is perfectly obvious, any consumers of your API may not be able to pick up on certain details.
Bad Practice
Consider a case where the class given below can be instantiated and provides certain functionalities within each instance in a thread-safe manner, perhaps it is a rest API client.
If there is no documentation comment on the class, it is not immediately obvious that the class is thread safe. Thus, multiple instances of the class may be created to perform operations concurrently, using up both memory as well as OS resources like sockets. If it were known from the beginning that the class were thread safe, the user would not need to create unnecessary extra instances of SomeClass
.
class SomeClass {
// ...
}
Recommended
Make sure to add useful information regarding the usage or implementation of a particular declaration, so that anything about it which can't be understood from the name or some other cue is correctly conveyed.
/**
* Instances of this class are used to perform xyz action.
*
* This class is thread safe and the same instance can be used over multiple threads.
*/
class SomeClass {
// ...
}
Exceptions
This issue will not be reported for model entity classes. If there is any non-obvious behavior associated with a particular class however, do consider documenting it.