diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/MT999.java b/test/java/foundation/pEp/jniadapter/test/speedtest/MT999.java new file mode 100644 index 0000000..ff3796b --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/MT999.java @@ -0,0 +1,194 @@ +package foundation.pEp.jniadapter.test.speedtest; + +import java.text.ParseException; +import java.util.regex.*; + +/** + * MT999 is a Free Format Message. + */ + +public class MT999 extends SWIFTMsg { + + String trn; + String rr; + String narrative; + + /** + * Construct MT999 message by parsing. + * + * @param txt text to parse + * @throws ParseException if not a valid MT999 message + */ + + public MT999(String txt) throws ParseException { + Matcher m = MTConstants.mt999_pattern.matcher(txt); + if (!m.matches()) + throw new ParseException("not a valid MT999 message", 0); + + // retrieve Basic Header and Application Header fields + retrieveHeader(m); + + // no User Header Block + + // Text Block + trn = m.group("trn"); + rr = m.group("rr"); + narrative = m.group("narrative"); + } + + /** + * Construct MT999 message. + * + * @param srcAddress is sender's address + * @param dstAddress is receiver's address + * @param dir "I" for incoming message "O" for + * outgoing message + * @param id transaction id + * @param payload freeform text + * @param session session number + * @param sequence sequence number + */ + + public MT999(String srcAddress, String dstAddress, String dir, String id, String relref, String payload, + String session, String sequence) { + + if (srcAddress.length() != 12) + throw new IllegalArgumentException("srcAddress must be 12 characters"); + if (dstAddress.length() != 12) + throw new IllegalArgumentException("dstAddress must be 12 characters"); + if (dir.compareTo("I") != 0 && dir.compareTo("O") != 0) + throw new IllegalArgumentException("dir must be I or O"); + if (id.length() < 1 || id.length() > 16) + throw new IllegalArgumentException("id must be between 1 and 12 characters"); + if (relref.length() > 16) + throw new IllegalArgumentException("related reference must be at most 16 characters"); + if (payload.length() < 1) + throw new IllegalArgumentException("payload must have a value"); + + if (session.length() != 4) + throw new IllegalArgumentException("session must be 4 digits"); + if (sequence.length() != 6) + throw new IllegalArgumentException("sequence must be 6 digits"); + + mt999(); + + logicalTerminalAddress = srcAddress; + destinationAddress = dstAddress; + inputIdentifier = dir; + + trn = id; + rr = relref; + narrative = payload; + + sessionNumber = session; + sequenceNumber = sequence; + } + + /** + * Construct MT999 message with defaults for session and sequence. + * + * @param srcAddress is sender's address + * @param dstAddress is receiver's address + * @param dir "I" for incoming message "O" for + * outgoing message + * @param id transaction id + * @param payload freeform text + */ + + public MT999(String srcAddress, String dstAddress, String dir, String id, String relref, String payload) { + + + if (srcAddress.length() != 12) + throw new IllegalArgumentException("srcAddress must be 12 characters"); + if (dstAddress.length() != 12) + throw new IllegalArgumentException("dstAddress must be 12 characters"); + if (dir.compareTo("I") != 0 && dir.compareTo("O") != 0) + throw new IllegalArgumentException("dir must be I or O"); + if (id.length() < 1 || id.length() > 16) + throw new IllegalArgumentException("id must be between 1 and 12 characters"); + if (relref.length() > 16) + throw new IllegalArgumentException("related reference must be at most 16 characters"); + if (payload.length() < 1) + throw new IllegalArgumentException("payload must have a value"); + + mt999(); + + logicalTerminalAddress = srcAddress; + destinationAddress = dstAddress; + inputIdentifier = dir; + + trn = id; + rr = relref; + narrative = payload; + + sessionNumber = "0000"; + sequenceNumber = "000000"; + } + + /** + * Convert MT999 message by composing. + * + * @param fmt rendering format + * @return string representation of MT999 message + */ + + public String toString(MTConstants.Format fmt) { + String result; + // FIXME: rework to stringbuffer + switch (fmt) { + case MTFIN: + // Basic Header Block + result = "{1:"; + result += applicationIdentifier; + result += serviceIdentifier; + result += logicalTerminalAddress; + result += sessionNumber; + result += sequenceNumber; + result += "}"; + + // Application Header Block + result += "{2:"; + result += inputIdentifier; + result += messageType; + result += destinationAddress; + result += messagePriority; + result += "}"; + + // no User Header Block + + // Text Block + result += "{4:\n"; + result += ":20:" + trn + "\n"; + if (rr != null && rr.length() > 0) + result += ":21:" + rr +"\n"; + result += ":79:\n" + narrative; + result += "\n-}"; + return result; + + case MTXML: + throw new UnsupportedOperationException("MTXML not yet implemented"); + } + + throw new AssertionError("this should never happen"); + } + + /** + * Convert MT999 message by composing. + * + * @return string representation of MT999 message + */ + + public String toString() { + return toString(MTConstants.Format.MTFIN); + } + + // MT999 specifica + + private void mt999() { + applicationIdentifier = "F"; // FIN + serviceIdentifier = "01"; // FIN + messageType = "999"; + messagePriority = "N"; + } + +} diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/MTConstants.java b/test/java/foundation/pEp/jniadapter/test/speedtest/MTConstants.java new file mode 100644 index 0000000..59b000f --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/MTConstants.java @@ -0,0 +1,60 @@ +package foundation.pEp.jniadapter.test.speedtest; + +import java.util.regex.Pattern; + +public class MTConstants { + + /** + * Rendering Format of a SWIFT message. + */ + + enum Format { + MTFIN, MTXML + } + + /** + * SWIFTMessages have a Basic Header Block and an Application Header Block + */ + + static final String mt_regex = "(?ms)" + // Basic Header Block + + "\\{1:" // + + "(?\\w)" // + + "(?\\d{2})" // + + "(?\\w{12})" // + + "(?\\d{4})" // + + "(?\\d{5,6})" // + + "\\}" + + // Application Header Block + + "\\{2:" // + + "(?I|O)" // + + "(?\\d{3})" // + + "(\\d{10})?" // + + "(?\\w{12})" // + + "(.*)?" // + + "(?U|N|S)" // + + "\\}" + + // FIXME: User Header Block (the wrong way). The trailing .* is to make it useable for basic swift and mt999 ... + + "(\\{3:?(.*)\\})?(.*)" // + ; + + static final Pattern mt_pattern = Pattern.compile(mt_regex); + + static final String mt999_regex = mt_regex + // Text Block + + "\\{4:\n" // + + ":20:(?\\w{1,16})\n" // + + "(:21:(?.{1,16})\n)?" // + + ":79:(?.*?)" // + + "\n-\\}" // + // trailer + + ".*" + + ; + + static final Pattern mt999_pattern = Pattern.compile(mt999_regex); + +} + diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/MtMsgCodec.java b/test/java/foundation/pEp/jniadapter/test/speedtest/MtMsgCodec.java new file mode 100644 index 0000000..9fafa6d --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/MtMsgCodec.java @@ -0,0 +1,480 @@ +package foundation.pEp.jniadapter.test.speedtest; + +import java.nio.charset.StandardCharsets; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Properties; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import foundation.pEp.jniadapter.Blob; +import foundation.pEp.jniadapter.Engine; +import foundation.pEp.jniadapter.Identity; +import foundation.pEp.jniadapter.Message; +import foundation.pEp.jniadapter.Pair; + +/** + * MTMsgCodec is the Codec class for encoding/decoding p≡p for SWIFT messages. + * + *

+ * See SWIFT message structure, MT message format, MT999 + *

+ *

+ * Copyright 2019, p≡p + * Security. + *

+ * + * @author Volker Birk + * @version %I% %G% + */ + +// FIXME: rework to stringbuffer + +public class MTMsgCodec { + public Engine pEp; + + /** + * Constructs a MessageCodec using p≡p engine. + * + * @param pEp_engine p≡p engine to use + */ + + public MTMsgCodec(Engine pEp_engine) { + pEp = pEp_engine; + } + + private final static String magicKeys = "pEpKeys"; + private final static String magicEnc = "pEpMessage"; + + private final static String pgp_regex = "(?ms)" + "-----BEGIN PGP (?.*?)-----\n" + "(\\w:.*?$\n)*" + "\n" + + "(?.*?)" + "-----END PGP (.*?)-----.*"; + + private static final Pattern pgp_pattern = Pattern.compile(pgp_regex); + + private static final String pgptypeMessage = "MESSAGE"; + private static final String pgptypePubkey = "PUBLIC KEY BLOCK"; + + // FIXME: private final static String uri_regex = "payto://swift/(?\\w+)"; + private final static String uri_regex = "(?\\w+)@BIC"; + + private final static Pattern uri_pattern = Pattern.compile(uri_regex); + + /** + * Strips PGP header and footer from encryption or key data. + * + * @param pgp_text text to work on + * @throws ParseException if text is not valid PGP data + * @return pgp_text without PGP header + */ + + protected static String stripFromPGP(String pgp_text) throws ParseException { + + Matcher m = pgp_pattern.matcher(pgp_text); + if (!m.matches()) + throw new ParseException("not a PGP block", 0); + + return m.group("block"); + } + + /** + * Adds PGP header and footer. + * + * @param payload text to decorate + * @param pgp_type PGP data type + * @return payload with added header and footer + */ + + protected static String addPGPHeader(String payload, String pgp_type) { + // FIXME: rework to stringbuffer + return "-----BEGIN PGP " + pgp_type + "-----\n\n" + payload + "\n-----END PGP " + pgp_type + "-----\n"; + } + + /** + * Decodes a BIC from an URI. + * + * @param uri the URI to decode from + * @throws ParseException if URI has not the correct form + * @return decoded BIC + */ + + public static String decodeBIC(String uri) throws ParseException { + Matcher m = uri_pattern.matcher(uri); + if (!m.matches()) + throw new ParseException("not a valid URI", 0); + + return m.group("bic"); + } + + /** + * Encodes a BIC into an URI. + * + * @param bic BIC to encode + * @return encoded URI + */ + + public static String encodeBIC(String bic) { + // return "payto://swift/" + bic + return bic + "@BIC"; + } + + /** + * Generates a list of transporting MT999 messages for a payload. + * + * @param from source address + * @param to destination address + * @param ii message direction + * @param trn message id + * @param payload payload to split + * @param magic magic string to mark as p≡p message + * + * @return array of String with MT999 messages + */ + + protected String[] transportMT999(String from, String to, String ii, String trn, String rr, String payload, + String magic) { + + Vector result = new Vector(); + payload = payload.trim(); + + int j = 1, f = 0, t = 0; + for (int i = payload.indexOf("\n"); i != -1; i = payload.indexOf("\n", i + 1), j++) { + + if (j % 34 == 0) { + t = i + 1; + String cont = t < payload.length() - 1 ? "." : ""; + MT999 mt999 = new MT999(from, to, ii, trn, rr, magic + "\n" + payload.substring(f, t) + cont); + result.add(mt999.toString()); + f = i + 1; + } + } + if (t < payload.length() - 1) { + int z = payload.charAt(payload.length() - 1) == '\n' ? 1 : 0; + MT999 mt999 = new MT999(from, to, ii, "23", // fixed trn + "", magic + "\n" + payload.substring(t, payload.length() - z)); + result.add(mt999.toString()); + } + + return result.toArray(new String[result.size()]); + } + + /** + * encodes a p≡p Message to a String with a serialized p≡p for SWIFT message. + * + * @param msg p≡p Message to encode if from or to are not set they're taken + * by parsing the header of longmsg; in this case + * message direction is being taken from there, too + * @param config properties with configuration + * @return String with encoded p≡p for SWIFT message + * @throws UnsupportedOperationException if EncFormat is other than + * None, Inline + * or PEP + */ + + public String encode(Message msg, Properties config) { + if (msg.getLongmsg() == null || msg.getLongmsg().length() < 1) + throw new IllegalArgumentException("longmsg must contain the message"); + + String result = ""; + + String msgid = msg.getId() != null && msg.getId().length() > 0 ? msg.getId() : "23"; + String dir = msg.getDir() == Message.Direction.Incoming ? "I" : "O"; + + if (msgid.length() > 12) { + if (msgid.substring(0, 3).compareTo("pEp.") == 0 && msgid.length() >= 15) + msgid = msgid.substring(4, 15); + else + msgid = msgid.substring(0, 11); + } + + String from = msg.getFrom() != null && msg.getFrom().address.length() > 0 ? msg.getFrom().address : null; + + String to = msg.getTo() != null && msg.getTo().size() > 0 && msg.getTo().elementAt(0).address.length() > 0 + ? msg.getTo().elementAt(0).address + : null; + + if (from != null) { + try { + from = decodeBIC(from); + if (from.length() != 12) + throw new IllegalArgumentException("from address must be URI with BIC12"); + } catch (ParseException ex) { + throw new IllegalArgumentException("from address must be URI with BIC12"); + } + } + + if (to != null) { + try { + to = decodeBIC(to); + if (to.length() != 12) + throw new IllegalArgumentException("to address must be URI with BIC12"); + } catch (ParseException ex) { + throw new IllegalArgumentException("to address must be URI with BIC12"); + } + } + + switch (msg.getEncFormat()) { + case None: + result = msg.getLongmsg(); // we send the message unmodified + if (result.substring(0, 3).compareTo("{1:") == 0) { + // probably SWIFT MTFIN + + if (from == null || to == null || msgid == null) { + // parse SWIFT header + SWIFTMsg mh = new SWIFTMsg(); + + try { + mh.parseHeader(result); + } catch (ParseException ex) { + throw new UnsupportedOperationException("unsupported message format"); + } + + if (from == null) + from = mh.logicalTerminalAddress; + if (to == null) + to = mh.destinationAddress; + dir = mh.inputIdentifier; + } + } else if (result.substring(0, 1).compareTo("<") == 0) { + // probably XML + + // FIXME: let's do the job for MTXML, too + return result; + } else { // we don't know this format, so let it be + return result; + } + + if(msg.getAttachments() != null) + for (int i = 0; i < msg.getAttachments().size(); ++i) { // FIXME: can attachments become null? + Blob attach = msg.getAttachments().elementAt(i); + String magic; + + if (attach.mime_type.compareToIgnoreCase("application/pgp-keys") == 0) + magic = magicKeys; + else + break; // don't know this MIME type + + // we send an MT999 with the keys + String payload; + try { + payload = stripFromPGP(new String(attach.data, StandardCharsets.UTF_8)); + } catch (ParseException ex) { + // cannot parse this + break; + } + + String[] msgs = transportMT999(from, to, dir, msgid, "", payload, magic); + + for (int j = 0; j < msgs.length; ++j) { + if (j > 0) + result += "\n"; + result += msgs[j].toString(); + } + } + break; + + case PEP: + case PGPMIME: + case Inline: + if (from == null || to == null) + throw new IllegalArgumentException("from and to must be set to URIs with BIC12"); + + String pgp_txt; + Vector attachments = null; + + if (msg.getEncFormat() == Message.EncFormat.PEP || msg.getEncFormat() == Message.EncFormat.PGPMIME) { + if (msg.getAttachments() == null || msg.getAttachments().size() != 2) + throw new IllegalArgumentException("no valid message format"); + Blob attach = msg.getAttachments().elementAt(1); + pgp_txt = new String(attach.data, StandardCharsets.UTF_8); + } else /* Inline */ { + pgp_txt = msg.getLongmsg(); + } + + String payload; + try { + payload = stripFromPGP(pgp_txt); + } catch (ParseException ex) { + // cannot parse this + throw new IllegalArgumentException("illegal encryption text"); + } + String[] msgs = transportMT999(from, to, dir, msgid, "", payload, magicEnc); + + for (int j = 0; j < msgs.length; ++j) { + if (j > 0) + result += "\n"; + result += msgs[j].toString(); + } + + if (msg.getEncFormat() == Message.EncFormat.Inline) { + String[] attached_key = null; + attachments = msg.getAttachments(); + + for (int i = 0; attachments != null && i < attachments.size(); ++i) { + Blob attach = attachments.elementAt(i); + if (attach.mime_type.compareTo("application/pgp-keys") == 0) { + // we send an MT999 with the keys + try { + payload = stripFromPGP(new String(attach.data, StandardCharsets.UTF_8)); + } catch (ParseException ex) { + // cannot parse this + break; + } + msgs = transportMT999(from, to, dir, msgid, "", payload, magicKeys); + + for (int j = 0; j < msgs.length; ++j) { + if (j > 0) + result += "\n"; + result += msgs[j].toString(); + } + } else { + throw new UnsupportedOperationException( + "only application/pgp-keys is supported with Inline but got " + attach.mime_type); + } + } + } + break; + + default: + throw new UnsupportedOperationException("unsupported encryption format"); + } + + return result; + } + + /** + * Creates p≡p message from MTFIN or MTXML using SWIFT header info + * + * @param header MTFIN header structure + * @param txt MTFIN message text + * @return p≡p message + */ + + protected Message pEpMessageFromSWIFTMessage(SWIFTMsg header, String txt) { + Message m = new Message(); + + Identity from = new Identity(); + from.address = encodeBIC(header.logicalTerminalAddress); + m.setFrom(from); + + Identity to = new Identity(); + to.address = encodeBIC(header.destinationAddress); + Vector _to = new Vector(); + _to.add(to); + m.setTo(_to); + + m.setDir(header.inputIdentifier.compareTo("I") == 0 ? Message.Direction.Incoming : Message.Direction.Outgoing); + + m.setLongmsg(txt); + + ArrayList> al = new ArrayList>(); + Pair field = new Pair("X-pEp-Version", pEp.getProtocolVersion()); + al.add(field); + m.setOptFields(al); + return m; + } + + /** + * decodes p≡p Messages from a String with serialized p≡p for SWIFT messages. + * + * @param txt String to decode from + * @throws ParseException if the String does not contain SWIFT messages only + * @return array with p≡p Messages + * + */ + + public Message[] decode(String txt) throws ParseException { + Vector result = new Vector(); + + if (txt.substring(0, 3).compareTo("{1:") == 0) { + // probably SWIFT MTFIN + + int f = 0; + int t = txt.indexOf("{1:", 3); + if (t == -1) + t = txt.length(); + + String key_payload = ""; + String enc_payload = ""; + while (f < txt.length()) { + String _txt = txt.substring(f, t); + + f = t; + t = txt.indexOf("{1:", f + 3); + if (t == -1) + t = txt.length(); + + Message last = null; + + SWIFTMsg m = new SWIFTMsg(); + m.parseHeader(_txt); + + boolean done = false; + if (m.messageType.compareTo("999") == 0) { + MT999 _m = new MT999(_txt); + String narrative = _m.narrative.trim(); + if (narrative.substring(0, magicKeys.length()).compareTo(magicKeys) == 0) { + key_payload += narrative.substring(magicKeys.length()).trim(); + if (key_payload.substring(key_payload.length()).compareTo(".") == 0) { + key_payload = key_payload.substring(0, key_payload.length() - 2); + } else { + // p≡p keys + String keydata = addPGPHeader(key_payload, pgptypePubkey); + key_payload = ""; + + if (last == null) + last = pEpMessageFromSWIFTMessage(m, "p≡p keys"); + + Vector a = new Vector(); + Blob b = new Blob(); + b.data = keydata.getBytes(StandardCharsets.UTF_8); + b.mime_type = "application/pgp-keys"; + b.filename = "pEpKeys.asc"; + a.add(b); + last.setAttachments(a); + + result.add(last); + last = null; + + } + done = true; + } else if (narrative.substring(0, magicEnc.length()).compareTo(magicEnc) == 0) { + // p≡p encrypted data + enc_payload += narrative.substring(magicEnc.length()).trim(); + if (enc_payload.substring(enc_payload.length()).compareTo(".") == 0) { + enc_payload = enc_payload.substring(0, enc_payload.length() - 2); + } else { + // p≡p encryption + String encdata = addPGPHeader(enc_payload, pgptypeMessage); + Message r = pEpMessageFromSWIFTMessage(m, encdata); + r.setEncFormat(Message.EncFormat.Inline); + result.add(r); + } + done = true; + } + } + + if (!done) { + last = pEpMessageFromSWIFTMessage(m, _txt); + result.add(last); + } + } + } else if (txt.substring(0, 1).compareTo("<") == 0) { + // probably XML + + // FIXME: let's do the job for MTXML, too + throw new UnsupportedOperationException("XML not yet implemented"); + } else { // we don't know this format + throw new ParseException("not a valid SWIFT message", 0); + } + + Message[] _result = new Message[result.size()]; + return result.toArray(_result); + } +} diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/SpeedTest.java b/test/java/foundation/pEp/jniadapter/test/speedtest/SpeedTest.java new file mode 100644 index 0000000..b6d971a --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/SpeedTest.java @@ -0,0 +1,275 @@ +package foundation.pEp.jniadapter.test.speedtest; + +import java.text.ParseException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.charset.StandardCharsets; +import java.util.Vector; +import java.util.Scanner; +import foundation.pEp.jniadapter.*; + +public class SpeedTest { + private static Engine pEp = new Engine(); + private static MTMsgCodec codec = new MTMsgCodec(pEp); + private static Identity me = new Identity(true); + private static Identity you = new Identity(); + + protected static void decodingTest(long n, String testDataEnc) { + for (long i=0; i keys = new Vector(); + Engine.decrypt_message_Return ret = pEp.decrypt_message(msgs[0], keys, 0); + String txt = ret.dst.getLongmsg(); + } + catch (ParseException ex) { + System.err.println("error: parsing test data"); + System.exit(3); + } + } + } + + protected class DecodingThread extends Thread { + private long _n; + private String _testDataEnc; + + public DecodingThread(long n, String testDataEnc) + { + _n = n; + _testDataEnc = testDataEnc; + } + + public void run() { + decodingTest(_n, _testDataEnc); + } + } + + private static Message encrypt(String data) { + Message m = new Message(); + m.setDir(Message.Direction.Outgoing); + m.setFrom(me); + Vector to = new Vector(); + to.add(you); + m.setTo(to); + m.setLongmsg(data); + return pEp.encrypt_message(m, null, Message.EncFormat.Inline); + } + + protected static void encodingTest(long n, String testData) { + for (long i=0; i 0 || decoding > 0)) { + System.err.println("arguments error: -d or -e (or both) must be used with a positive number"); + System.exit(1); + } + + if (deth < 1 || enth < 1 || deth > 1024 || enth > 1024) { + System.err.println("arguments error: -jd or -je must be used with a positive number (max 1024)"); + System.exit(1); + } + + me.address = MTMsgCodec.encodeBIC("232323232323"); + me.username = "sender"; + me.user_id = "23"; + pEp.myself(me); + + you.address = MTMsgCodec.encodeBIC("424242424242"); + you.username = "receiver"; + you.user_id = me.user_id; + pEp.myself(you); // make a key for it + + Message enc = encrypt(testData); + String testDataEnc = codec.encode(enc, null); + + long startTime = System.nanoTime(); + + if (decoding > 0) { + if (deth == 1) { + decodingTest(decoding, testDataEnc); + } + else { + SpeedTest st = new SpeedTest(); + Thread[] dts = new Thread[deth]; + for (int i=0; i < deth; ++i) { + dts[i] = st.new DecodingThread(decoding, testDataEnc); + dts[i].start(); + } + for (int i=0; i < deth; ++i) { + try { + dts[i].join(); + } + catch (InterruptedException ex) { } + } + } + } + + long decodingTime = System.nanoTime(); + long decodingDelta = decodingTime - startTime; + + if (encoding > 0) { + if (enth == 1) { + encodingTest(decoding, testData); + } + else { + SpeedTest st = new SpeedTest(); + Thread[] ets = new Thread[enth]; + for (int i=0; i < enth; ++i) { + ets[i] = st.new EncodingThread(encoding, testData); + ets[i].start(); + } + for (int i=0; i < enth; ++i) { + try { + ets[i].join(); + } + catch (InterruptedException ex) { } + } + } + } + + long encodingDelta = System.nanoTime() - decodingTime; + + double ent = (double) encodingDelta / 1000000000; + double det = (double) decodingDelta / 1000000000; + + double enr = (double) encoding / ent; + double der = (double) decoding / det; + + System.out.println(String.format( + "encrypted and encoded %d messages in %.3f sec. (%.1f msg./sec. per core)\n" + + "decrypted and decoded %d messages in %.3f sec. (%.1f msg./sec. per core)", + encoding, ent, enr, decoding, det, der)); + } +} diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/SwiftMSG.java b/test/java/foundation/pEp/jniadapter/test/speedtest/SwiftMSG.java new file mode 100644 index 0000000..268992a --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/SwiftMSG.java @@ -0,0 +1,58 @@ +package foundation.pEp.jniadapter.test.speedtest; + +import java.text.ParseException; +import java.util.regex.*; + +public class SWIFTMsg { + // Basic Header Block + public String applicationIdentifier; + public String serviceIdentifier; + public String logicalTerminalAddress; + public String sessionNumber; + public String sequenceNumber; + + // Application Header Block + public String inputIdentifier; + public String messageType; + public String destinationAddress; + public String messagePriority; + + /** + * retrieve header fields of Basic Header Block and Application Header + * Block + * + * @param m Matcher object of a regex result + */ + + public void retrieveHeader(Matcher m) { + // Basic Header Block + applicationIdentifier = m.group("ai"); + serviceIdentifier = m.group("si"); + logicalTerminalAddress = m.group("lta"); + sessionNumber = m.group("sn"); + sequenceNumber = m.group("sqn"); + + // Application Header Block + inputIdentifier = m.group("ii"); + messageType = m.group("mt"); + destinationAddress = m.group("da"); + messagePriority = m.group("mp"); + } + + /** + * parse MTFIN header and retrieve header fields into variables. + * + * @param txt MTxxx message to parse + * @throws ParseException if not a valid MTxxx message + */ + + public void parseHeader(String txt) throws ParseException { +// String header = txt.substring(0, 50); + + Matcher m = MTConstants.mt_pattern.matcher(txt); + if (!m.matches()) + throw new ParseException("not a valid MTxxx message", 0); + + retrieveHeader(m); + } +} diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/speedtest.sh b/test/java/foundation/pEp/jniadapter/test/speedtest/speedtest.sh new file mode 100644 index 0000000..4f4fd65 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/speedtest.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +ENGINE_LIB_PATH=$HOME/local-default/lib + +export HOME=../resources/per-user-dirs/alice +export LD_LIBRARY_PATH=$ENGINE_LIB_PATH +export DYLD_LIBRARY_PATH=$ENGINE_LIB_PATH + +cd ../../../../../ +java -enableassertions -Xcheck:jni -cp .:../../src -Djava.library.path=.:../../src foundation.pEp.jniadapter.test.speedtest.SpeedTest $@