这是一个更大问题的一部分,我们需要将旧应用程序移植到新设备(当然还有另一种编程语言/框架)。经过很多努力(嗅探通信线路,对传输的数据进行逆向工程大约2-3周),我设法缩小了我认为包含2个数字的4个字节。其中一个是温度读数,如30.51,30.46等,如第一列(表01)所示。另一个值是一个浮点数,可以在3.9到3.6之间(甚至更低,有4个小数)。 4个十六进制字节(表01的第2列)应包含这两个值。我不得不做一些逆向工程,因为没有可用的文档和源代码。我设法缩小了java代码的部分,我认为将十六进制字符串解码为2个数字。有人能够检查代码是否是我认为的代码?我不是一个java程序员,我主要处理其他编程语言。所以我需要几件事
表01
30.51 => 01:53:4e:98
30.46 => 01:53:8e:94
30.43 => 01:53:8e:91
30.39 => 01:53:8e:8e
30.39 => 01:53:4e:8e
12.36 => 01:52:88:b1
16.01 => 01:52:c9:cf
18.65 => 01:52:ca:a5
21.14 => 01:52:8b:74
如果有任何需要的信息,请告诉我,因为我花了很多时间试图解决这个问题。如果需要,我可以记录更多数字。
Btw左边的数字是温度读数(以摄氏度为单位)。那么“可能”最终会涉及乘法来得到数字?我不太确定,但我想我会提到我对此的了解。
我没有时间学习java来解决这个问题(我们处理java是非常罕见的)而且我已经花了将近一个月的时间来解决这个问题。真的很感激任何帮助,只是清除这个障碍。这是将十六进制解码为2个数字的java代码。我通过对传统应用程序进行逆向工程来获得此请注意,我删除了之前发布的反编译代码,因为我刚刚意识到它已被NDA涵盖。
哎呀,我犯了一个错误,就是没有提到最终需要将其插入到Python程序中 - 因为我提到它是一个更大的Python项目的一部分,几乎所有我编码并且工作得很好的项目。并且没有提及(并忘记添加Python标签)的巨大道歉。我将不得不用Python重写它。答案 0 :(得分:3)
左起第4列中的C,8和4值不会影响值。这让我觉得每个值只发送了12位信息。也许它是ADC的整数原始输出?如果是这种情况,那么您可以使用以下内容对其进行解码:
double valueOne(long input) {
long x = input & 0xFFF;
double m = (30.51 - 12.36) / (0xE98 - 0x8B1);
int c = 0xE91;
double b = 30.43;
return m*(x-c)+b;
}
m*(x-c+b)
线性近似是为了使它尽可能准确地围绕看起来像你的工作点;您可以根据需要调整m,c,b值。
要处理其他值,请创建一个类似的例程,屏蔽并移位以获得正确的12位并提供所需的m,c和b校准值。
这是计算表1值的原因:
3:4e:98 30.514
3:8e:94 30.466
3:8e:91 30.430
3:4e:8e 30.393
3:4e:8e 30.393
2:88:b1 12.364
2:c9:cf 15.799
2:ca:a5 18.370
2:8b:74 20.856
最低值不太合适;也许最好从不同于12.36点的值推断出来(参见m
值的公式)。或许这是热电偶数据,这不是线性的。需要了解更多关于实际电路的评论。
答案 1 :(得分:3)
反编译代码会计算温度:
如您所料,反编译代码class a
能够计算温度。方法double a()
具有算法。反编译的代码无法编译,但经过一段时间的工作后,它已得到纠正(见下文),并根据您的输入和预期值准确计算温度。
结果:(使用mapKey = 77)
30.506 => 01:53:4e:98
30.460 => 01:53:8e:94
30.425 => 01:53:8e:91
30.391 => 01:53:8e:8e
30.391 => 01:53:4e:8e
12.338 => 01:52:88:b1
15.990 => 01:52:c9:cf
18.636 => 01:52:ca:a5
21.127 => 01:52:8b:74
<强>校准:
方法a()
- 现在称为calculateTemperature()
,如果您选择使用它,似乎已内置校准。在4个参数中,第一个是十六进制字符串(算法仅使用两个八位字节),另外三个可以校准结果。很难知道如何使用这些值。但如果您将它们保留为我在main()
中显示的默认值,则会正确计算得到的温度。也许您知道为什么要校准结果。其中一个校准需要传递65到85之间的值(我使用的是77)。还有另一个类似的参数导致结果的乘法(零会忽略参数)。我发现使用mapKey = 77会产生稍微过低的结果(但是78稍微过高)。我发现使用100175的比例使得结果更接近预期值。第三次校准是+/-类型的校准(零将忽略参数)。
可能计算电压
计算温度后,当温度在33.2和36.0之间时,有一些代码指定值约为0.2-2.0。我把这个电压称为电压,但不知道它是什么。对于您的输入值,温度始终低于33.2,因此这部分代码实际上是无用的。
未知方法c()的含义
有一种小方法c()
。它为您提供的值返回4.16 - 4.18左右的值。这对你来说意味着什么吗?
工作代码:
main()
方法演示了如何从十六进制字符串中获取温度,并打印输入数据的结果。代码在您在问题中提到的网站上运行。值得注意的是,3个校准参数不需要是byte[]
个数组,可以更简单地理解并用作类型int
。如果您对代码有任何疑问,可以在评论(或聊天)中工作,我会向您解释。
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Meter {
private List<Double> parameterList = new ArrayList<>(); // Used by the temperature algorithm
private Map<Integer, Double> scaleMap = new HashMap<>(21); // Used to scale (not necessarily required)
public static void main(String[] args) {
Meter meter = new Meter();
meter.initData();
//30.51 => 01:53:4e:98
//30.46 => 01:53:8e:94
//30.43 => 01:53:8e:91
//30.39 => 01:53:8e:8e
//30.39 => 01:53:4e:8e
//12.36 => 01:52:88:b1
//16.01 => 01:52:c9:cf
//18.65 => 01:52:ca:a5
//21.14 => 01:52:8b:74
// Test each of the provided hex values
int mapKey = 77; // 77 seemed the best value; 78 was a bit too high
String[] values = { "01:53:4e:98", "01:53:8e:94", "01:53:8e:91", "01:53:8e:8e",
"01:53:4e:8e", "01:52:88:b1", "01:52:c9:cf", "01:52:ca:a5", "01:52:8b:74" };
ByteBuffer key = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(mapKey);
ByteBuffer scale = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(0); // A number around 100175 perhaps provides better results
ByteBuffer offset = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(0); // No offset
for (int i=0; i<values.length; i++) {
double tempC = meter.calculateTemperature(hexStringToByteArray(values[i]), key.array(), scale.array(), offset.array());
System.out.printf("%2.3f => %s\n", tempC, values[i]);
}
}
/**
* Convert a hex string (which may contain the `:` character) to a byte array
* @param hexString 4 octets of the form xx:xx:xx:xx
* @return The byte array
*/
static byte[] hexStringToByteArray(String hexString) {
hexString = hexString.replaceAll(":", "");
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i+1), 16));
}
return data;
}
/**
* Populate the algorithm parameters (required), and the scaling factors (not necessarily required)
*/
private void initData() {
scaleMap.put(65, 29.629);
scaleMap.put(66, 29.660);
scaleMap.put(67, 29.691);
scaleMap.put(68, 29.722);
scaleMap.put(69, 29.753);
scaleMap.put(70, 29.784);
scaleMap.put(71, 29.815);
scaleMap.put(72, 29.846);
scaleMap.put(73, 29.877);
scaleMap.put(74, 29.908);
scaleMap.put(75, 29.939);
scaleMap.put(76, 29.970);
scaleMap.put(77, 30.001);
scaleMap.put(78, 30.032);
scaleMap.put(79, 30.063);
scaleMap.put(80, 30.094);
scaleMap.put(81, 30.125);
scaleMap.put(82, 30.156);
scaleMap.put(83, 30.187);
scaleMap.put(84, 30.218);
scaleMap.put(85, 30.249);
parameterList.add(52.94);
parameterList.add(49.61);
parameterList.add(46.51);
parameterList.add(43.62);
parameterList.add(40.94);
parameterList.add(38.44);
parameterList.add(36.12);
parameterList.add(33.95);
parameterList.add(31.93);
parameterList.add(30.05);
parameterList.add(28.29);
parameterList.add(26.61);
parameterList.add(25.05);
parameterList.add(23.59);
parameterList.add(22.23);
parameterList.add(20.96);
parameterList.add(19.76);
parameterList.add(18.65);
parameterList.add(17.60);
parameterList.add(16.63);
parameterList.add(15.71);
parameterList.add(14.84);
parameterList.add(14.02);
parameterList.add(13.25);
parameterList.add(12.53);
parameterList.add(11.86);
parameterList.add(11.22);
parameterList.add(10.63);
parameterList.add(10.07);
parameterList.add(9.541);
parameterList.add(9.046);
parameterList.add(8.572);
parameterList.add(8.126);
parameterList.add(7.706);
parameterList.add(7.311);
parameterList.add(6.938);
parameterList.add(6.588);
parameterList.add(6.257);
parameterList.add(5.946);
parameterList.add(5.651);
parameterList.add(5.374);
parameterList.add(5.109);
parameterList.add(4.859);
parameterList.add(4.623);
parameterList.add(4.400);
parameterList.add(4.189);
parameterList.add(3.990);
parameterList.add(3.801);
parameterList.add(3.623);
parameterList.add(3.454);
parameterList.add(3.294);
parameterList.add(3.141);
parameterList.add(2.996);
parameterList.add(2.858);
parameterList.add(2.728);
parameterList.add(2.604);
parameterList.add(2.487);
parameterList.add(2.376);
parameterList.add(2.270);
parameterList.add(2.170);
parameterList.add(2.075);
parameterList.add(1.984);
parameterList.add(1.897);
parameterList.add(1.815);
parameterList.add(1.737);
parameterList.add(1.662);
parameterList.add(1.591);
parameterList.add(1.524);
parameterList.add(1.459);
parameterList.add(1.398);
parameterList.add(1.340);
parameterList.add(1.284);
parameterList.add(1.231);
parameterList.add(1.180);
parameterList.add(1.132);
parameterList.add(1.086);
parameterList.add(1.042);
parameterList.add(1.000);
parameterList.add(0.9599);
parameterList.add(0.9216);
parameterList.add(0.8851);
parameterList.add(0.8501);
parameterList.add(0.8168);
parameterList.add(0.7849);
parameterList.add(0.7545);
parameterList.add(0.7254);
parameterList.add(0.6974);
parameterList.add(0.6707);
parameterList.add(0.6451);
parameterList.add(0.6207);
parameterList.add(0.5973);
parameterList.add(0.5743);
parameterList.add(0.5523);
parameterList.add(0.5313);
parameterList.add(0.5112);
parameterList.add(0.4920);
parameterList.add(0.4736);
parameterList.add(0.4560);
parameterList.add(0.4392);
parameterList.add(0.4230);
parameterList.add(0.4076);
parameterList.add(0.3925);
parameterList.add(0.3781);
parameterList.add(0.3642);
parameterList.add(0.3510);
parameterList.add(0.3383);
parameterList.add(0.3261);
parameterList.add(0.3144);
parameterList.add(0.3032);
parameterList.add(0.2925);
parameterList.add(0.2822);
parameterList.add(0.2722);
parameterList.add(0.2626);
parameterList.add(0.2534);
parameterList.add(0.2445);
parameterList.add(0.2360);
parameterList.add(0.2279);
parameterList.add(0.2201);
parameterList.add(0.2126);
parameterList.add(0.2054);
parameterList.add(0.1984);
parameterList.add(0.1917);
parameterList.add(0.1852);
parameterList.add(0.1790);
parameterList.add(0.1731);
parameterList.add(0.1673);
parameterList.add(0.1618);
parameterList.add(0.1564);
parameterList.add(0.1513);
parameterList.add(0.1464);
parameterList.add(0.1416);
parameterList.add(0.1370);
parameterList.add(0.1326);
parameterList.add(0.1283);
parameterList.add(0.1242);
parameterList.add(0.1203);
parameterList.add(0.1164);
parameterList.add(0.1128);
parameterList.add(0.1092);
parameterList.add(0.1058);
parameterList.add(0.1026);
}
/**
*
* @param b1array The hex number b1:b2:b3:b4 (as a byte array)
* - The only bits used are b2 (6 low bits & x3f) and b3
* (all 8 bits & xff)
* @param mapKey
* - Value from 65 to 85; if 77 then scale is 1.0; otherwise < 77
* or > 77 causes scaling
* @param byte1Scale
* - Equal to zero (scale=1), or units in micro (10E6) where
* scale=value/10E6
* @param byte1Offset
* - Measured in 10E6 (micro) - offset amount
* @return The temperature in degrees Celsius
*/
public double calculateTemperature(byte[] b1array, byte[] mapKey, byte[] byte1Scale, byte[] byte1Offset) {
double scale;
int scaleMicroValue = ByteBuffer.wrap(byte1Scale).order(ByteOrder.LITTLE_ENDIAN).getInt();
if (scaleMicroValue == 0) {
scale = 1.0D;
} else {
scale = scaleMicroValue / 1000000.0D;
}
double offsetValue = ByteBuffer.wrap(byte1Offset).order(ByteOrder.LITTLE_ENDIAN).getInt() / 1000000.0D;
/* 14 bits: b2_5 b2_4 ... b2_0 b3_7 .. b3_0 */
byte byte2 = b1array[2];
byte byte3 = b1array[3];
int bitValue = (byte3 & 0xFF | (byte2 & 0x3F) << 8);
double scaledBitValue = bitValue * scale - offsetValue;
int key = (byte) (mapKey[0] & 0xFF);
double mapValue = scaleMap.containsKey(key) ? scaleMap.get(key) : scaleMap.get(77);
double param1 = 0.0;
double param2 = parameterList.get(0);
double result = 33.0D / scaledBitValue * (8191.0D - scaledBitValue) / mapValue;
int i = 0;
int j = parameterList.size();
double minParameter = parameterList.get(j - 1);
if (param2 < result || minParameter > result)
return 0;
int index = 0;
boolean process = true;
while (i < j && process) {
if (result >= parameterList.get(i)) {
if (i == 0) {
param1 = parameterList.get(i);
param2 = parameterList.get(i + 1);
index = i;
process = false;
}
if (process) {
param1 = parameterList.get(i - 1);
param2 = parameterList.get(i);
index = i - 1;
}
process = false;
}
if (process)
i++;
}
if (process) {
index = 0;
param2 = 0;
}
double voltage = 0.0; // I don't even know if this is voltage (but it is only calculated if temp between 33.2 and 36
double tempC = index + (result - param1) / (param2 - param1) - 40.0D;
if ((tempC < 34.0D) && (tempC >= 33.2D)) {
voltage = 1.95D;
}
while (true) {
if ((tempC < 34.1D) && (tempC >= 34.0D)) {
voltage = 1.881D;
} else if ((tempC < 34.2D) && (tempC >= 34.1D)) {
voltage = 1.805D;
} else if ((tempC < 34.3D) && (tempC >= 34.2D)) {
voltage = 1.71D;
} else if ((tempC < 34.4D) && (tempC >= 34.3D)) {
voltage = 1.615D;
} else if ((tempC < 34.5D) && (tempC >= 34.4D)) {
voltage = 1.52D;
} else if ((tempC < 34.6D) && (tempC >= 34.5D)) {
voltage = 1.4249999999999998D;
} else if ((tempC < 34.7D) && (tempC >= 34.6D)) {
voltage = 1.3299999999999998D;
} else if ((tempC < 34.8D) && (tempC >= 34.7D)) {
voltage = 1.2349999999999999D;
} else if ((tempC < 34.9D) && (tempC >= 34.8D)) {
voltage = 1.14D;
} else if ((tempC < 35.0D) && (tempC >= 34.9D)) {
voltage = 1.045D;
} else if ((tempC < 35.1D) && (tempC >= 35.0D)) {
voltage = 0.95D;
} else if ((tempC < 35.2D) && (tempC >= 35.1D)) {
voltage = 0.855D;
} else if ((tempC < 35.3D) && (tempC >= 35.2D)) {
voltage = 0.76D;
} else if ((tempC < 35.4D) && (tempC >= 35.3D)) {
voltage = 0.6649999999999999D;
} else if ((tempC < 35.5D) && (tempC >= 35.4D)) {
voltage = 0.57D;
} else if ((tempC < 35.6D) && (tempC >= 35.5D)) {
voltage = 0.475D;
} else if ((tempC < 35.7D) && (tempC >= 35.6D)) {
voltage = 0.38D;
} else if ((tempC < 35.8D) && (tempC >= 35.7D)) {
voltage = 0.285D;
} else if ((tempC < 35.9D) && (tempC >= 35.8D)) {
voltage = 0.19D;
} else {
if (tempC >= 36.0D) {
break;
}
if (tempC < 35.9D) {
break;
}
voltage = 0.095D;
}
}
return tempC;
}
/**
* I don't know what this function is: It always calculates around 4.16 - 4.18
* @param bArray The hex number b1:b2:b3:b4 (as a byte array)
* Uses:
* byte0: Low 2 bits
* byte1: all bits
* byte2: high 2 bits
* @return I don't know the significance of this value
*/
public double m(byte[] bArray) {
int byte2 = bArray[2];
int byte1 = bArray[1];
int byte0 = bArray[0];
return 0.003077674645823156D * (((byte0 & 0x3) << 2 | (byte1 & 0xC0) >> 6) << 8
| (byte2 & 0xC0) >> 6 | (byte1 & 0x3F) << 2);
}
}
编辑:接受十六进制字符串作为参数和输出温度的方法
/**
* Arg[0] is expected to be the input (a hex string)
* The output is the temperature (printed to the console)
* @param args One value; The hex string
*/
public static void main(String[] args) {
Meter meter = new Meter();
meter.initData();
int mapKey = 77; // Scaling factor
ByteBuffer key = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(mapKey);
ByteBuffer scale = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(1000180); // No scaling
ByteBuffer offset = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(0); // No offset
byte[] hexString = hexStringToByteArray(args[0]);
double tempC = meter.calculateTemperature(hexString, key.array(), scale.array(), offset.array());
System.out.printf("%.2f", tempC);
}
答案 2 :(得分:2)
我不得不做一些逆向工程,因为没有可用的文档和源代码。
我喜欢Java的是它可以“轻松”反编译。
由于您正在将某些内容移植到新设备上,我将假设您有权围绕源代码进行反编译和调整。
有一些网站如this one,可以为您提供很多帮助。
这可能无法直接解决问题,但希望您能够弄清楚它们是如何编码的:)
答案 3 :(得分:2)
如果你想反编译字节码,只需使用反编译器。您可以在IDE中使用this page或使用JD插件。 IntelliJ IDEA或Eclipse有一个内置的Decompiler,只需打开它中的.class文件并读取反编译代码。
如果您只想解码一些十六进制字符串而不是字节码,请使用this website
顺便说一下,如果你真的想构建自己的十六进制字符串解码器,我认为使用一堆if else语句并不是一个好主意。十六进制编码/解码只是移动一些位的过程。使用<<
或>>
运算符可以使代码更短,更易于阅读。可以this article帮助你。
答案 4 :(得分:2)
我在Quora上看过这篇文章。
您要求提供可用于在Java中反编译十六进制的代码。我不清楚你在哪里得到这个代码。但是我接受了上面的代码,看到最后一个函数将一个字节数组转换为一个double,然后使用它。你可以看到它不起作用,甚至一直以错误的方式来获得温度。 包括用于比较位值的便捷调试功能。 也许其他位需要以某种方式与这个双重交互。
另外,你确定你的例子都是正确的吗?通常,此处的股息相似,但有些则大不相同。 (运行程序!)如果这段代码是合法的,我会期望相同的红利,至少在错误中。然后,所需要的只是调整用于乘以位的常量。
请注意,C ++中的这些操作是相同的。主要区别在于类型转换在C ++中具有更简单的语法(即没有ByteBuffer语法或类库)。在Java中,一个字节只是一个8位有符号的int。因为它是一个整数,所以几个隐式类型转换很方便。
这在https://www.compilejava.net/上运行。 要进行其他测试,只需将代码添加到main(...)方法。
抱歉,我不知道为什么会粘贴双倍空间。
import java.nio.ByteBuffer;
public class CrazyConvertor {
// int t = Integer.decode("0x01");
// System.out.println("test is "+t+"\t01");
// t = Integer.decode("0x24");
// System.out.println("test is "+t+"\t36");
//30.51 => 01:53:4e:98
//30.46 => 01:53:8e:94
//30.43 => 01:53:8e:91
//30.39 => 01:53:8e:8e
//30.39 => 01:53:4e:8e
//12.36 => 01:52:88:b1
//16.01 => 01:52:c9:cf
//18.65 => 01:52:ca:a5
//21.14 => 01:52:8b:74
public static double[] temperatures;
public static int[] encodedBytes;
static {
temperatures = new double[9];
encodedBytes = new int[9];
encodedBytes[0] = Integer.decode("0x01534e98");
encodedBytes[1] = Integer.decode("0x01538e94");
encodedBytes[2] = Integer.decode("0x01538e91");
encodedBytes[3] = Integer.decode("0x01538e8e");
encodedBytes[4] = Integer.decode("0x01534e8e");
encodedBytes[5] = Integer.decode("0x015288b1");
encodedBytes[6] = Integer.decode("0x0152c9cf");
encodedBytes[7] = Integer.decode("0x0152caa5");
encodedBytes[8] = Integer.decode("0x01528b74");
temperatures[0] = 30.51;
temperatures[1] = 30.46;
temperatures[2] = 30.43;
temperatures[3] = 30.39;
temperatures[4] = 30.39;
temperatures[5] = 12.36;
temperatures[6] = 16.01;
temperatures[7] = 18.65;
temperatures[8] = 21.14;
}
static int MASK = 0x0003ffc0;
public static void main(String[] args)
{
for (int k=0; k<9; k++){
double f = fourBytesToDouble(encodedBytes[k]);
int x = integerElegantConversion(encodedBytes[k]);
System.out.println("Converted double \t"+f);
System.out.println("Converted double elegant \t"+fourBytesElegantConversion(encodedBytes[k]));
System.out.println("Target value\t"+temperatures[k]);
System.out.println("Dividend\t"+temperatures[k]/f);
System.out.println("Dividend temp by integer\t"+temperatures[k]/x);
System.out.println();
}
}
/**
* takes four bytes
* function identical to m below, but easier to read
*
* Key programmer's note: in java, a byte is a 8-bit integer
* So this is basically dynamic type conversion from encoded bits to a double.
*
* @param z and integer representing 4 bytes
* @return
*/
public static double fourBytesToDouble(int z){
//read 12 bits from middle of 3 byte array
byte[] bytes = ByteBuffer.allocate(4).putInt(z).array();
//grab 4 bits from first byte from bits 0 thru 1 and bits 6 thru 7 of byte 2
int x = ((bytes[1] & 0x3) << 2 | (bytes[2] & 0xC0) >> 6);
x = x << 8;
//grab second byte from bits 2 thru 7 of byte 1 and bits 0 thru 1 of byte 2
int y = (bytes[2] & 0x3F) << 2 | (bytes[3] & 0xC0) >> 6;
int r = x | y; //or the bytes, so you obtain 12 bits; four from byte 1 and eight from byte 2
System.out.println(" fourBytesToDouble (int) \t"+r);
return 0.003077674645823156D * new Double(r);
}
/**
* original reference function
* @param paramArrayOfByte
* @return
*/
public static double m(byte[] paramArrayOfByte)
{
int i = paramArrayOfByte[2];
int j = paramArrayOfByte[1];
return 0.003077674645823156D * (((paramArrayOfByte[0] & 0x3) << 2 | (paramArrayOfByte[1] & 0xC0) >> 6) << 8 | (i & 0xC0) >> 6 | (j & 0x3F) << 2);
}
/**
* Same task using integer masking.
* Probably the original code that got obfuscated by compiler
* @param x
* @return
*/
public static double fourBytesElegantConversion(int x){
//// ByteBuffer bb = ByteBuffer.allocate(4).put(b);
//// bb.position(0);
//// int x = (bb.getInt() << 10) >> 10;
//// System.out.println(" x\t"+fourBytesBinaryString(x));
//// System.out.println("mask\t"+fourBytesBinaryString(MASK));
// x = x & MASK;
//// System.out.println(" x1\t"+fourBytesBinaryString(x));
// x = x >> 6;
x = (x & MASK) >> 6;
System.out.println(" fourBytesElegantConversion (int)\t"+x);
return 0.003077674645823156D * new Double(x);
}
public static int integerElegantConversion(int x) {
return (x & MASK) >> 6;
}
/**
* helper function to compare bits
* @param x
* @return
*/
public static String fourBytesBinaryString(int x){
String r = Integer.toBinaryString(x);
int extra = 32 - r.length();
for (int i=0; i < extra; i++){
r = "0"+r;
}
return r;
}
/**
* helper function to compare bits
* @param b
* @return
*/
public static String eightBytesBinaryString(byte[] b){
String r = oneByteBinaryString(b[0]);
for (int k=1; k < 8; k++) r += oneByteBinaryString(b[k]);
return r;
}
/**
* helper function to compare bits
* @param b
* @return
*/
public static String fourBytesBinaryString(byte[] b){
String r = oneByteBinaryString(b[0]);
for (int k=1; k < 4; k++) r += oneByteBinaryString(b[k]);
return r;
}
/**
* helper function to compare bits; helper function to above
* @param b
* @return
*/
private static String oneByteBinaryString(byte b) {
String r = Integer.toBinaryString(b);
if (b < 0){
r = r.substring(24);
} else {
int extra = 8 - r.length();
for (int i = 0; i < extra; i++) {
r = "0" + r;
}
}
return r;
}
}
编辑:复制/粘贴错误