Decompiler improvement, compiler improvement
This commit is contained in:
parent
d9bfbf2bc5
commit
68c221eb32
12
pom.xml
12
pom.xml
@ -54,4 +54,16 @@
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>14</source>
|
||||
<target>14</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,5 +1,6 @@
|
||||
package com.alterdekim.flash.decompiler;
|
||||
|
||||
import com.alterdekim.flash.decompiler.compiler.FlashCompiler;
|
||||
import com.alterdekim.flash.decompiler.tag.DoAction;
|
||||
import com.alterdekim.flash.decompiler.tag.TagType;
|
||||
import com.alterdekim.flash.decompiler.translator.Flash2Java;
|
||||
@ -8,12 +9,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
@Slf4j
|
||||
public class Main {
|
||||
public static void main(String[] args) throws Exception {
|
||||
FlashDecompiler decompiler = new FlashDecompiler();
|
||||
ShockwaveFile file = decompiler.loadFromFile(new File("D:\\Documents\\rtmpSpring\\static\\swf\\cache\\rus\\catalogs[18].swf")); //
|
||||
ShockwaveFile file = decompiler.loadFromFile(new File("catalogs.swf")); // D:\Documents\FlashProjects\Untitled-2.swf
|
||||
|
||||
DoAction da = (DoAction) file.getTags()
|
||||
.stream()
|
||||
@ -25,6 +29,7 @@ public class Main {
|
||||
File out = new File("dec.json");
|
||||
if( out.exists() ) out.delete();
|
||||
//objectMapper.writeValue(out, new Flash2Java(da).convert());
|
||||
new Java2Flash().convert(new Flash2Java(da).convert());
|
||||
var j2f = new Java2Flash().convert(new Flash2Java(da).convert());
|
||||
Files.write(Path.of("./export1.swf"), new FlashCompiler(j2f).compile(), StandardOpenOption.CREATE);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.alterdekim.flash.decompiler.action;
|
||||
|
||||
import com.alterdekim.flash.decompiler.util.ActionField;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class ActionConstantPool extends ByteCodeAction {
|
||||
|
||||
private List<String> pool;
|
||||
|
||||
@Override
|
||||
public ActionField getType() {
|
||||
return ActionField.ConstantPool;
|
||||
}
|
||||
}
|
@ -2,16 +2,14 @@ package com.alterdekim.flash.decompiler.action;
|
||||
|
||||
import com.alterdekim.flash.decompiler.util.ActionField;
|
||||
import com.alterdekim.flash.decompiler.item.ByteCodeItem;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class ActionPush extends ByteCodeAction {
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.alterdekim.flash.decompiler.compiler;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
public interface CompileObject {
|
||||
List<Byte> compile();
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.alterdekim.flash.decompiler.compiler;
|
||||
|
||||
import com.alterdekim.flash.decompiler.tag.*;
|
||||
import com.alterdekim.flash.decompiler.translator.Java2Flash;
|
||||
import com.alterdekim.flash.decompiler.util.ByteUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class FlashCompiler {
|
||||
private final Java2Flash pcode;
|
||||
|
||||
public byte[] compile() {
|
||||
List<Byte> data = new ArrayList<>();
|
||||
data.addAll(List.of((byte) 0x46, (byte) 0x57, (byte) 0x53));
|
||||
data.add((byte) 0x08); // swf version (8)
|
||||
List<Byte> d1 = new ArrayList<>();
|
||||
d1.addAll(List.of((byte) 0x30, (byte) 0x0A, (byte) 0x00, (byte) 0xA0)); // rect
|
||||
d1.addAll(List.of((byte) 0x00, (byte) 0x19)); // frameRate
|
||||
d1.addAll(ByteUtil.intToBytes(1)); // frames Count
|
||||
//List<CompileObject> tags = List.of(new SetBackgroundColor(new byte[] {0,0,0}), new DoAction(pcode.getPool(), pcode.getActions()), new ShowFrame(), new End());
|
||||
//d1.addAll(tags.stream().map(CompileObject::compile).flatMap(Collection::stream).collect(Collectors.toList()));
|
||||
d1.addAll(new SetBackgroundColor(new byte[] {0,0,0}).compile());
|
||||
d1.addAll(new DoAction(pcode.getPool(), pcode.getActions()).compile());
|
||||
d1.addAll(new ShowFrame().compile());
|
||||
d1.addAll(new End().compile());
|
||||
// fileSize u32
|
||||
log.info("fileSize u32: {}", d1.size());
|
||||
data.addAll(ByteUtil.intToBytes32(d1.size()));
|
||||
data.addAll(d1);
|
||||
return ByteUtil.toPrimitive(data);
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package com.alterdekim.flash.decompiler.item;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class BooleanItem extends ByteCodeItem {
|
||||
|
||||
private Boolean val;
|
||||
|
@ -1,18 +1,26 @@
|
||||
package com.alterdekim.flash.decompiler.tag;
|
||||
|
||||
import com.alterdekim.flash.decompiler.action.ActionConstantPool;
|
||||
import com.alterdekim.flash.decompiler.action.ActionPush;
|
||||
import com.alterdekim.flash.decompiler.action.ByteCodeAction;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import com.alterdekim.flash.decompiler.compiler.CompileObject;
|
||||
import com.alterdekim.flash.decompiler.util.ActionField;
|
||||
import com.alterdekim.flash.decompiler.util.ByteUtil;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@Getter
|
||||
@Setter
|
||||
public class DoAction extends ShockwaveTag {
|
||||
@AllArgsConstructor
|
||||
public class DoAction extends ShockwaveTag implements CompileObject {
|
||||
|
||||
private List<String> actionPool;
|
||||
private List<ByteCodeAction> actions;
|
||||
@ -21,4 +29,61 @@ public class DoAction extends ShockwaveTag {
|
||||
public TagType getType() {
|
||||
return TagType.DoAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> compile() {
|
||||
List<Byte> bytes = new ArrayList<>();
|
||||
this.actions.forEach(action -> {
|
||||
bytes.add(action.getType().id);
|
||||
switch(action.getType()) {
|
||||
case Push:
|
||||
ActionPush push = (ActionPush) action;
|
||||
List<Byte> data = new ArrayList<>();
|
||||
push.getItems().forEach(item -> {
|
||||
data.add((byte) item.getType().type);
|
||||
switch (item.getType()) {
|
||||
case STRING:
|
||||
data.addAll(fromString((String) item.getValue()));
|
||||
break;
|
||||
case INTEGER:
|
||||
data.addAll(ByteUtil.intToBytes32((Integer) item.getValue()));
|
||||
break;
|
||||
case POOL_INDEX:
|
||||
Integer index = (Integer) item.getValue();
|
||||
data.addAll(index < 256 ? ByteUtil.intToBytes8(index) : ByteUtil.intToBytes(index));
|
||||
break;
|
||||
case DOUBLE:
|
||||
data.addAll(ByteUtil.doubleToBytes((Double) item.getValue()));
|
||||
break;
|
||||
case BOOLEAN:
|
||||
data.add((byte) ((Boolean) item.getValue() ? 0x01 : 0x00));
|
||||
break;
|
||||
}
|
||||
});
|
||||
bytes.addAll(ByteUtil.intToBytes(data.size()));
|
||||
bytes.addAll(data);
|
||||
break;
|
||||
case ConstantPool:
|
||||
ActionConstantPool pool = (ActionConstantPool) action;
|
||||
bytes.addAll(ByteUtil.intToBytes(pool.getPool().size())); // maybe there should also be u8 size of data
|
||||
pool.getPool().forEach(s -> {
|
||||
bytes.addAll(fromString(s));
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
bytes.add((byte) 0x0);
|
||||
int val = getType().getId() << 6;
|
||||
val |= 63; // 265955
|
||||
return Stream.of( ByteUtil.intToBytes(val), ByteUtil.intToBytes32(bytes.size()+6), bytes ).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Byte> fromString(String s) {
|
||||
List<Byte> l = new ArrayList<>();
|
||||
for( char c : s.toCharArray() ) {
|
||||
l.add((byte) c);
|
||||
}
|
||||
l.add((byte) 0x0);
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
22
src/main/java/com/alterdekim/flash/decompiler/tag/End.java
Normal file
22
src/main/java/com/alterdekim/flash/decompiler/tag/End.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.alterdekim.flash.decompiler.tag;
|
||||
|
||||
import com.alterdekim.flash.decompiler.compiler.CompileObject;
|
||||
import com.alterdekim.flash.decompiler.util.ByteUtil;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
public class End extends ShockwaveTag implements CompileObject {
|
||||
@Override
|
||||
public TagType getType() {
|
||||
return TagType.End;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> compile() {
|
||||
return ByteUtil.fromPrimitive(new byte[] {0, 0});
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.alterdekim.flash.decompiler.tag;
|
||||
|
||||
import com.alterdekim.flash.decompiler.compiler.CompileObject;
|
||||
import com.alterdekim.flash.decompiler.util.ByteUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ToString
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class SetBackgroundColor extends ShockwaveTag implements CompileObject {
|
||||
|
||||
private byte[] backgroundColor;
|
||||
|
||||
@Override
|
||||
public TagType getType() {
|
||||
return TagType.SetBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> compile() {
|
||||
int val = getType().getId() << 6;
|
||||
val |= 3;
|
||||
return Stream.of(ByteUtil.intToBytes(val), ByteUtil.fromPrimitive(backgroundColor)).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.alterdekim.flash.decompiler.tag;
|
||||
|
||||
import com.alterdekim.flash.decompiler.compiler.CompileObject;
|
||||
import com.alterdekim.flash.decompiler.util.ByteUtil;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
public class ShowFrame extends ShockwaveTag implements CompileObject {
|
||||
@Override
|
||||
public TagType getType() {
|
||||
return TagType.ShowFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> compile() {
|
||||
int val = this.getType().getId() << 6;
|
||||
return ByteUtil.intToBytes(val);
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package com.alterdekim.flash.decompiler.tag;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum TagType {
|
||||
SetBackgroundColor(9),
|
||||
DoAction(12),
|
||||
|
@ -131,7 +131,7 @@ public class Flash2Java {
|
||||
m.put(index, this.vars.get(valToString(val)));
|
||||
return;
|
||||
}
|
||||
m.put(index, val.getValue());
|
||||
m.put(index, valConverter(val));
|
||||
return;
|
||||
}
|
||||
Map<String, Object> m = recursiveGet((ArrayDeque<String>) varOrMember.getValue());
|
||||
@ -139,7 +139,7 @@ public class Flash2Java {
|
||||
m.put(index, this.vars.get(valToString(val)));
|
||||
return;
|
||||
}
|
||||
m.put(index, val.getValue());
|
||||
m.put(index, valConverter(val));
|
||||
}
|
||||
|
||||
private Map<String, Object> recursiveGet(Deque<String> l) {
|
||||
@ -169,7 +169,7 @@ public class Flash2Java {
|
||||
}
|
||||
|
||||
private void setVariable() {
|
||||
Object val = this.stack.pop().getValue();
|
||||
Object val = valConverter( this.stack.pop() );
|
||||
String variableName = valToString( this.stack.pop() );
|
||||
this.vars.put(variableName, val);
|
||||
}
|
||||
@ -186,7 +186,7 @@ public class Flash2Java {
|
||||
this.vars.put(name, this.vars.get(valToString(val)));
|
||||
return;
|
||||
}
|
||||
this.vars.put(name, val.getValue());
|
||||
this.vars.put(name, valConverter(val));
|
||||
}
|
||||
|
||||
private String fromPool(int index) {
|
||||
|
@ -1,36 +1,115 @@
|
||||
package com.alterdekim.flash.decompiler.translator;
|
||||
|
||||
import com.alterdekim.flash.decompiler.action.ByteCodeAction;
|
||||
import com.alterdekim.flash.decompiler.action.*;
|
||||
import com.alterdekim.flash.decompiler.item.*;
|
||||
import com.alterdekim.flash.decompiler.item.internal.InitObjectItem;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.compress.harmony.unpack200.bytecode.ByteCode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class Java2Flash {
|
||||
private Set<String> pool;
|
||||
|
||||
public List<ByteCodeAction> convert(Map<String, Object> map) {
|
||||
this.pool = new HashSet<>(65535);
|
||||
extractAllStrings(map);
|
||||
log.info("poolSet: {}", this.pool);
|
||||
return new ArrayList<>();
|
||||
private List<String> pool;
|
||||
private List<ByteCodeAction> actions;
|
||||
|
||||
public Java2Flash convert(Map<String, Object> map) {
|
||||
this.actions = new ArrayList<>();
|
||||
this.pool = new ArrayList<>();
|
||||
this.pool.addAll(extractAllStrings(new HashSet<>(65535), map)); // maybe make a check if hashset size is bigger than initialCapacity
|
||||
this.actions.add(new ActionConstantPool(this.pool));
|
||||
map.keySet().forEach(k -> createVariable(map, k));
|
||||
map.keySet().stream().filter(k -> map.get(k).getClass().getSimpleName().equals("HashMap")).forEach(k -> setMembers(map, k));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void extractAllStrings(Map<String, Object> map) {
|
||||
private void setMembers(Map<String, Object> map, String key) {
|
||||
HashMap<String, Object> m = (HashMap<String, Object>) map.get(key);
|
||||
m.keySet().forEach(k -> {
|
||||
this.actions.add(new ActionPush(Collections.singletonList(fromString(key))));
|
||||
this.actions.add(new ActionGetVariable());
|
||||
this.actions.add(new ActionPush(switch (m.get(k).getClass().getSimpleName()) {
|
||||
case "String" -> List.of(fromString(k), fromString((String) m.get(k)));
|
||||
case "Integer" -> List.of(fromString(k), new IntegerItem((Integer) m.get(k)));
|
||||
case "Double" -> List.of(fromString(k), new DoubleItem((Double) m.get(k)));
|
||||
case "Boolean" -> List.of(fromString(k), new BooleanItem((Boolean) m.get(k)));
|
||||
default -> List.of(fromString(k));
|
||||
}));
|
||||
if( m.get(k).getClass().getSimpleName().equals("HashMap") ) {
|
||||
HashMap<String, Object> s = (HashMap<String, Object>) m.get(k);
|
||||
parseHashMapMember(s);
|
||||
this.actions.add(new ActionPush(Collections.singletonList(new IntegerItem(s.keySet().size()))));
|
||||
this.actions.add(new ActionInitObject());
|
||||
}
|
||||
this.actions.add(new ActionSetMember());
|
||||
});
|
||||
}
|
||||
|
||||
private void parseHashMapMember(Map<String, Object> m) {
|
||||
m.keySet().forEach(key -> {
|
||||
switch (m.get(key).getClass().getSimpleName()) {
|
||||
case "String":
|
||||
this.actions.add(new ActionPush(List.of(fromString(key), fromString((String) m.get(key)))));
|
||||
break;
|
||||
case "Integer":
|
||||
this.actions.add(new ActionPush(List.of(fromString(key), new IntegerItem((Integer) m.get(key)))));
|
||||
break;
|
||||
case "Double":
|
||||
this.actions.add(new ActionPush(List.of(fromString(key), new DoubleItem((Double) m.get(key)))));
|
||||
break;
|
||||
case "Boolean":
|
||||
this.actions.add(new ActionPush(List.of(fromString(key), new BooleanItem((Boolean) m.get(key)))));
|
||||
break;
|
||||
case "HashMap":
|
||||
HashMap<String, Object> s = (HashMap<String, Object>) m.get(key);
|
||||
parseHashMapMember(s);
|
||||
this.actions.add(new ActionPush(Collections.singletonList(new IntegerItem(s.keySet().size()))));
|
||||
this.actions.add(new ActionInitObject());
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createVariable(Map<String, Object> map, String key) {
|
||||
List<ByteCodeItem> items = new ArrayList<>();
|
||||
items.add(fromString(key));
|
||||
log.info("Type: {}", map.get(key).getClass().getSimpleName());
|
||||
items.add(switch (map.get(key).getClass().getSimpleName()) {
|
||||
case "String" -> fromString((String) map.get(key));
|
||||
case "Integer" -> new IntegerItem((Integer) map.get(key));
|
||||
case "Double" -> new DoubleItem((Double) map.get(key));
|
||||
case "Boolean" -> new BooleanItem((Boolean) map.get(key));
|
||||
default -> new IntegerItem(0);
|
||||
});
|
||||
this.actions.add(new ActionPush(items));
|
||||
if( map.get(key).getClass().getSimpleName().equals("HashMap") ) {
|
||||
this.actions.add(new ActionInitObject());
|
||||
}
|
||||
this.actions.add(new ActionDefineLocal());
|
||||
}
|
||||
|
||||
private ByteCodeItem fromString(String s) {
|
||||
int i = this.pool.indexOf(s);
|
||||
return i != -1 ? new PoolIndexItem(i) : new StringItem(s);
|
||||
}
|
||||
|
||||
private Set<String> extractAllStrings(Set<String> pool, Map<String, Object> map) {
|
||||
map.keySet().forEach(k -> {
|
||||
if(k.matches("[^0-9].+")) {
|
||||
try {
|
||||
Integer.parseInt(k);
|
||||
} catch (Exception e) {
|
||||
pool.add(k);
|
||||
}
|
||||
});
|
||||
map.values().forEach(o -> {
|
||||
switch( o.getClass().getSimpleName() ) {
|
||||
case "HashMap":
|
||||
extractAllStrings((HashMap<String, Object>) o);
|
||||
break;
|
||||
case "String":
|
||||
pool.add((String) o);
|
||||
break;
|
||||
switch (o.getClass().getSimpleName()) {
|
||||
case "HashMap" -> extractAllStrings(pool, (HashMap<String, Object>) o);
|
||||
case "String" -> pool.add((String) o);
|
||||
}
|
||||
});
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Slf4j
|
||||
public class ByteUtil {
|
||||
@ -24,6 +27,36 @@ public class ByteUtil {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static byte[] int2bytes(int val, int len) {
|
||||
byte[] r = new byte[len];
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
r[i] = (byte) ( (val >> 8*i) & 0xFF );
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static List<Byte> intToBytes(int i) {
|
||||
return fromPrimitive(int2bytes(i, 2));
|
||||
}
|
||||
|
||||
public static List<Byte> intToBytes8(int i) {
|
||||
return fromPrimitive(int2bytes(i, 1));
|
||||
}
|
||||
|
||||
public static List<Byte> intToBytes32(int i) {
|
||||
return fromPrimitive(int2bytes(i, 4));
|
||||
}
|
||||
|
||||
public static List<Byte> fromPrimitive(byte[] b) {
|
||||
return IntStream.range(0, b.length).boxed().map(i -> b[i]).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static byte[] toPrimitive(List<Byte> b) {
|
||||
byte[] a = new byte[b.size()];
|
||||
IntStream.range(0, b.size()).boxed().forEach(i -> a[i] = b.get(i));
|
||||
return a;
|
||||
}
|
||||
|
||||
public static double bytesToDouble(byte[] bytes) {
|
||||
byte[] b1 = new byte[8];
|
||||
for( int i = bytes.length-1, u = 0; i >= 0; i--, u++ ) {
|
||||
@ -34,4 +67,12 @@ public class ByteUtil {
|
||||
System.arraycopy(Arrays.copyOfRange(b1, 0, 4), 0, d, 4, 4);
|
||||
return ByteBuffer.wrap(d).order(ByteOrder.BIG_ENDIAN).getDouble();
|
||||
}
|
||||
|
||||
public static List<Byte> doubleToBytes(double d) {
|
||||
byte[] b = ByteBuffer.allocate(8).putDouble(d).array();
|
||||
byte[] b1 = new byte[8];
|
||||
System.arraycopy(b, 0, b1, 4, 4);
|
||||
System.arraycopy(b, 4, b1, 0, 4);
|
||||
return fromPrimitive(b1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user