1 package net.sf.openrocket.motor;
3 import java.io.UnsupportedEncodingException;
4 import java.security.MessageDigest;
5 import java.security.NoSuchAlgorithmException;
7 import net.sf.openrocket.util.TextUtil;
9 public class MotorDigest {
11 private static final double EPSILON = 0.00000000001;
13 public enum DataType {
14 /** An array of time points at which data is available (in ms) */
16 /** Mass data for a few specific points (normally initial and empty mass) (in 0.1g) */
17 MASS_SPECIFIC(1, 10000),
18 /** Mass per time (in 0.1g) */
19 MASS_PER_TIME(2, 10000),
20 /** CG position for a few specific points (normally initial and final CG) (in mm) */
22 /** CG position per time (in mm) */
24 /** Thrust force per time (in mN) */
25 FORCE_PER_TIME(5, 1000);
27 private final int order;
28 private final int multiplier;
29 DataType(int order, int multiplier) {
31 this.multiplier = multiplier;
33 public int getOrder() {
36 public int getMultiplier() {
42 private final MessageDigest digest;
43 private boolean used = false;
44 private int lastOrder = -1;
47 public MotorDigest() {
49 digest = MessageDigest.getInstance("MD5");
50 } catch (NoSuchAlgorithmException e) {
51 throw new IllegalStateException("MD5 digest not supported by JRE", e);
56 public void update(DataType type, int ... values) {
58 // Check for correct order
59 if (lastOrder >= type.getOrder()) {
60 throw new IllegalArgumentException("Called with type="+type+" order="+type.getOrder()+
61 " while lastOrder=" + lastOrder);
63 lastOrder = type.getOrder();
66 digest.update(bytes(type.getOrder()));
68 // Digest the data length
69 digest.update(bytes(values.length));
73 digest.update(bytes(v));
79 private void update(DataType type, int multiplier, double ... values) {
81 int[] intValues = new int[values.length];
82 for (int i=0; i<values.length; i++) {
87 intValues[i] = (int) Math.round(v);
89 update(type, intValues);
92 public void update(DataType type, double ... values) {
93 update(type, type.getMultiplier(), values);
96 private static double next(double v) {
97 return v + Math.signum(v) * EPSILON;
101 public String getDigest() {
103 throw new IllegalStateException("MotorDigest already used");
106 byte[] result = digest.digest();
107 return TextUtil.hexString(result);
112 private byte[] bytes(int value) {
114 (byte) ((value>>>24) & 0xFF), (byte) ((value>>>16) & 0xFF),
115 (byte) ((value>>>8) & 0xFF), (byte) (value & 0xFF)
122 public static String digestComment(String comment) {
123 comment = comment.replaceAll("\\s+", " ").trim();
125 MessageDigest digest;
127 digest = MessageDigest.getInstance("MD5");
128 } catch (NoSuchAlgorithmException e) {
129 throw new IllegalStateException("MD5 digest not supported by JRE", e);
133 digest.update(comment.getBytes("UTF-8"));
134 } catch (UnsupportedEncodingException e) {
135 throw new IllegalStateException("UTF-8 encoding not supported by JRE", e);
138 return TextUtil.hexString(digest.digest());