openepcis / openepcis-event-hash-generator Goto Github PK
View Code? Open in Web Editor NEWProject to generate event hash for EPCIS document/event in XML/JSON-LD format.
Home Page: https://openepcis.io
License: Apache License 2.0
Project to generate event hash for EPCIS document/event in XML/JSON-LD format.
Home Page: https://openepcis.io
License: Apache License 2.0
I am unhappy with RESTful parameter names and functionality and it just came to my mind that it might be a good idea to match parameter with cli.
Proposal: rename to "algorithm", maybe also support short form "a"
Additional functionality:
allow list of algorithms. TDB: comma seperated?
Proposal: change to "join", similar to what we have in cli and support short form "j"
Proposal: also support shot form "p"
The Quarkus framework support GraalVM native image build.
To make the runtime even smaller and thus required less resource, the container images shall be provided a native images as well.
Hi,
I compared again the outputs of our algorithms and I think you forgot a few rules that are listed in the official algorithm (in the cbv standard).
For example, you don't order pre-hash strings based on case-sensitive lexical ordering. You also don't support the new GS1 Web URI ( 'https://ref.gs1.org/cbv' ).
Here is an example of an output of our algorithm:
eventType=ObjectEvent
eventTime=2005-04-05T02:33:31.116Z
eventTimeZoneOffset=-06:00
epcListepc=https://id.gs1.org/01/10614141073464/21/2017
epc=https://id.gs1.org/01/10614141073464/21/2018
epc=https://id.gs1.org/01/10614141073464/21/2019
action=ADD
bizStep=https://ref.gs1.org/cbv/BizStep-receiving
disposition=https://ref.gs1.org/cbv/Disp-in_progress
readPointid=https://id.gs1.org/414/0012345111112/254/593
bizLocationid=https://id.gs1.org/414/0012345111112/254/3
destinationListtype=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776
type=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776
type=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776
sensorElementListsensorElementsensorMetadatatime=2023-01-16T16:54:06.227Z
startTime=2019-04-02T12:55:01.000Z
endTime=2019-04-02T13:55:00.000Z
deviceID=https://id.gs1.org/8004/4000001111
deviceMetadata=https://id.gs1.org/8004/4000001111
rawData=https://id.gs1.org/8004/401234599999
dataProcessingMethod=https://id.gs1.org/253/4012345000054987
bizRules=https://id.gs1.org/253/4012345000054987
sensorReporttype=https://gs1.org/voc/Temperature
deviceID=https://id.gs1.org/8004/4000001252
deviceMetadata=https://id.gs1.org/8004/4000001111
rawData=https://id.gs1.org/8004/401234599999
dataProcessingMethod=https://id.gs1.org/253/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=https://ref.gs1.org/cbv/Comp-x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/8004/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorReporttype=https://gs1.org/voc/Temperature
deviceID=https://id.gs1.org/8004/400000134
deviceMetadata=https://id.gs1.org/8004/4000001111
rawData=https://id.gs1.org/8004/401234599999
dataProcessingMethod=https://id.gs1.org/253/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=https://ref.gs1.org/cbv/Comp-x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/8004/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorReporttype=https://gs1.org/voc/Temperature
deviceID=https://id.gs1.org/8004/4000001799
deviceMetadata=https://id.gs1.org/8004/4000001111
rawData=https://id.gs1.org/8004/401234599999
dataProcessingMethod=https://id.gs1.org/253/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=https://ref.gs1.org/cbv/Comp-x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/8004/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorElementListsensorElementsensorMetadata{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport{http://ns.example.com/epcis/}someFurtherMetadata=someText
{http://ns.example.com/epcis/}myField=my_custom_value
Here is the associated document:
{
"type": "EPCISDocument",
"@context": [
"https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
{
"example": "http://ns.example.com/epcis/",
"ext1": "http://example.com/ext1/",
"ext2": "http://example.com/ext2/",
"ext3": "http://example.com/ext3/",
"evt": "https://evrythng.com/context"
}
],
"schemaVersion": "2.0",
"creationDate": "2013-06-04T14:59:02.099+02:00",
"epcisBody": {
"eventList": [
{
"eventTimeZoneOffset": "-06:00",
"eventTime": "2005-04-05T02:33:31.116Z",
"type": "ObjectEvent",
"recordTime": "2005-04-05T02:33:31.116Z",
"epcList": [
"urn:epc:id:sgtin:0614141.107346.2019",
"urn:epc:id:sgtin:0614141.107346.2018",
"urn:epc:id:sgtin:0614141.107346.2017"
],
"@context": {
"example": "http://ns.example.com/epcis/",
"ext1": "http://example.com/ext1/"
},
"action": "ADD",
"bizStep": "receiving",
"disposition": "in_progress",
"readPoint": {
"id": "urn:epc:id:sgln:0012345.11111.593"
},
"bizLocation": {
"id": "urn:epc:id:sgln:0012345.11111.3"
},
"destinationList": [
{
"type": "location",
"destination": "urn:epc:id:sgln:0614141.00777.0"
},
{
"type": "location",
"destination": "urn:epc:id:sgln:0614141.00777.0"
},
{
"type": "location",
"destination": "urn:epc:id:sgln:0614141.00777.0"
}
],
"sensorElementList": [
{
"sensorMetadata": {
"time": "2023-01-16T16:54:06.227Z",
"deviceID": "urn:epc:id:giai:4000001.111",
"deviceMetadata": "https://id.gs1.org/giai/4000001111",
"rawData": "https://example.org/giai/401234599999",
"startTime": "2019-04-02T12:55:01.000Z",
"endTime": "2019-04-02T13:55:00.000Z",
"dataProcessingMethod": "https://example.com/gdti/4012345000054987",
"bizRules": "https://example.com/gdti/4012345000054987",
"example:someFurtherMetadata": "someText"
},
"sensorReport": [
{
"type": "Temperature",
"deviceID": "urn:epc:id:giai:4000001.252",
"rawData": "https://example.org/giai/401234599999",
"dataProcessingMethod": "https://example.com/gdti/4012345000054987",
"time": "2019-07-19T13:00:00.000Z",
"microorganism": "https://www.ncbi.nlm.nih.gov/taxonomy/1126011",
"chemicalSubstance": "https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N",
"value": 26,
"component": "x",
"stringValue": "SomeString",
"booleanValue": true,
"hexBinaryValue": "f0f0f0",
"uriValue": "https://id.gs1.org/giai/4000001111",
"minValue": 26,
"maxValue": 26.2,
"meanValue": 13.2,
"percRank": 50,
"percValue": 12.7,
"uom": "CEL",
"sDev": 0.1,
"deviceMetadata": "https://id.gs1.org/giai/4000001111",
"example:someFurtherMetadata": "someText"
},
{
"type": "Temperature",
"deviceID": "urn:epc:id:giai:4000001.799",
"rawData": "https://example.org/giai/401234599999",
"dataProcessingMethod": "https://example.com/gdti/4012345000054987",
"time": "2019-07-19T13:00:00.000Z",
"microorganism": "https://www.ncbi.nlm.nih.gov/taxonomy/1126011",
"chemicalSubstance": "https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N",
"value": 26,
"component": "x",
"stringValue": "SomeString",
"booleanValue": true,
"hexBinaryValue": "f0f0f0",
"uriValue": "https://id.gs1.org/giai/4000001111",
"minValue": 26,
"maxValue": 26.2,
"meanValue": 13.2,
"percRank": 50,
"percValue": 12.7,
"uom": "CEL",
"sDev": 0.1,
"deviceMetadata": "https://id.gs1.org/giai/4000001111",
"example:someFurtherMetadata": "someText"
},
{
"type": "Temperature",
"deviceID": "urn:epc:id:giai:4000001.34",
"rawData": "https://example.org/giai/401234599999",
"dataProcessingMethod": "https://example.com/gdti/4012345000054987",
"time": "2019-07-19T13:00:00.000Z",
"microorganism": "https://www.ncbi.nlm.nih.gov/taxonomy/1126011",
"chemicalSubstance": "https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N",
"value": 26,
"component": "x",
"stringValue": "SomeString",
"booleanValue": true,
"hexBinaryValue": "f0f0f0",
"uriValue": "https://id.gs1.org/giai/4000001111",
"minValue": 26,
"maxValue": 26.2,
"meanValue": 13.2,
"percRank": 50,
"percValue": 12.7,
"uom": "CEL",
"sDev": 0.1,
"deviceMetadata": "https://id.gs1.org/giai/4000001111",
"example:someFurtherMetadata": "someText"
}
],
"example:myField": "my_custom_value"
}
],
"eventID": "ni:///sha-256;9b64040b80d4d8a63fd694a3bed949ccf7c8bd402506f9eaed3f7e1f01d5f8ca?ver=CBV2.0"
}
]
}
}
Here is yours:
eventType=ObjectEvent
eventTime=2005-04-05T02:33:31.116Z
eventTimeZoneOffset=-06:00
epcList
epc=https://id.gs1.org/01/10614141073464/21/2017
epc=https://id.gs1.org/01/10614141073464/21/2018
epc=https://id.gs1.org/01/10614141073464/21/2019
action=ADD
bizStep=https://ref.gs1.org/cbv/BizStep-receiving
disposition=https://ref.gs1.org/cbv/Disp-in_progress
readPoint
id=https://id.gs1.org/414/0012345111112/254/593
bizLocation
id=https://id.gs1.org/414/0012345111112/254/3
destinationList
type=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776/254/0
type=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776/254/0
type=https://ref.gs1.org/cbv/SDT-location
destination=https://id.gs1.org/414/0614141007776/254/0
sensorElementList
sensorElement
sensorMetadata
time=2023-01-16T16:54:06.227Z
startTime=2019-04-02T12:55:01.000Z
endTime=2019-04-02T13:55:00.000Z
deviceID=https://id.gs1.org/8004/4000001111
deviceMetadata=https://id.gs1.org/giai/4000001111
rawData=https://example.org/giai/401234599999
dataProcessingMethod=https://example.com/gdti/4012345000054987
bizRules=https://example.com/gdti/4012345000054987
sensorReport
type=Temperature
deviceID=https://id.gs1.org/8004/4000001252
deviceMetadata=https://id.gs1.org/giai/4000001111
rawData=https://example.org/giai/401234599999
dataProcessingMethod=https://example.com/gdti/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/giai/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorReport
type=Temperature
deviceID=https://id.gs1.org/8004/4000001799
deviceMetadata=https://id.gs1.org/giai/4000001111
rawData=https://example.org/giai/401234599999
dataProcessingMethod=https://example.com/gdti/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/giai/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorReport
type=Temperature
deviceID=https://id.gs1.org/8004/400000134
deviceMetadata=https://id.gs1.org/giai/4000001111
rawData=https://example.org/giai/401234599999
dataProcessingMethod=https://example.com/gdti/4012345000054987
time=2019-07-19T13:00:00.000Z
microorganism=https://www.ncbi.nlm.nih.gov/taxonomy/1126011
chemicalSubstance=https://identifiers.org/inchikey:CZMRCDWAGMRECN-UGDNZRGBSA-N
value=26
component=x
stringValue=SomeString
booleanValue=true
hexBinaryValue=f0f0f0
uriValue=https://id.gs1.org/giai/4000001111
minValue=26
maxValue=26.2
meanValue=13.2
sDev=0.1
percRank=50
percValue=12.7
uom=CEL
sensorElementList
sensorElement
sensorMetadata
{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport
{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport
{http://ns.example.com/epcis/}someFurtherMetadata=someText
sensorReport
{http://ns.example.com/epcis/}someFurtherMetadata=someText
{http://ns.example.com/epcis/}myField=my_custom_value
I am sorry, I know we don't have the same indentation format for the pre-hash string, but I hope it still helps!
As per the recommendation from @RalphTro, according to the latest changes to the CBV document (i.e. CBV 2.1) need to adjust the Event Hash Generator pre-hash string as follows:
sensorElementList
should appear before the sensorElement
.?ver=CBV2.1
)@RalphTro Please let us know if something is missing or needs to be corrected.
Hi,
First of all, thanks a lot for you open source implementation. It is super useful.
I tested your algorithm, and compared it to ours (https://github.com/evrythng/epcis2.js#generating-a-hashed-id-for-an-event)
I compared with this EPCIS document:
{
"@context": "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
"id": "_:document1",
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate": "2005-07-11T11:30:47.0Z",
"epcisBody": {
"eventList": [
{
"type": "ObjectEvent",
"action": "OBSERVE",
"bizStep": "shipping",
"disposition": "in_transit",
"epcList": ["urn:epc:id:sgtin:0614141.107346.2017", "urn:epc:id:sgtin:0614141.107346.2018"],
"eventTime": "2005-04-03T20:33:31.116000-06:00",
"eventTimeZoneOffset": "-06:00",
"readPoint": { "id": "urn:epc:id:sgln:0614141.07346.1234" },
"bizTransactionList": [
{
"type": "po",
"bizTransaction": "http://transaction.acme.com/po/12345678"
}
]
}
]
}
}
The pre-hash string I got from your algorithm is:
eventType=ObjectEvent
eventTime=2005-04-04T02:33:31.116Z
eventTimeZoneOffset=-06:00
epcList
epc=https://id.gs1.org/01/10614141073464/21/2017
epc=https://id.gs1.org/01/10614141073464/21/2018
action=OBSERVE
bizStep=https://ref.gs1.org/voc/Bizstep-shipping
disposition=https://ref.gs1.org/voc/Disp-in_transit
readPoint
id=https://id.gs1.org/414/0614141073467/254/1234
bizTransactionList
bizTransaction=http://transaction.acme.com/po/12345678
type=https://ref.gs1.org/voc/BTT-po
Whereas I got this from ours:
eventType=ObjectEvent
eventTime=2005-04-04T02:33:31.116Ze
ventTimeZoneOffset=-06:00
epcList
epc=https://id.gs1.org/01/10614141073464/21/2017
epc=https://id.gs1.org/01/10614141073464/21/2018
action=OBSERVE
bizStep=https://ref.gs1.org/cbv/BizStep-shipping
disposition=https://ref.gs1.org/cbv/Disp-in_transit
readPoint
id=https://id.gs1.org/414/0614141073467/254/1234
bizTransactionList
type=https://ref.gs1.org/cbv/BTT-po
bizTransaction=http://transaction.acme.com/po/12345678
There are two differences:
If an EPCIS event is represented in JSON/JSON-LD, standard vocabulary elements are not expressed as URIs, but in bare string notation (i.e. 'in_transit' instead of 'https://ref.gs1.org/cbv/Disp-in_transit'). All standard vocabulary elements expressed in bare string notation SHALL be expanded to their corresponding GS1 Web URI (starting with 'https://ref.gs1.org/cbv').
- bizTransactionList – bizTransaction (business transaction type, business transaction ID)
For most of the fields that has a type field, the latter should be first in the associated prehash string.
I hope this helps! :)
Regards,
Clément
Creating the issue on behalf of @RalphTro to track all the issues that were reported by him and also support OpenEPCIS Event Hash Generator for both CBV 2.0 and CBV 2.1:
User Extensions are not sorted correctly:
When the following EPCIS document is passed then the generated userextensions in pre-hash are ordered as follows:
sensorElement
sensorReport
{https://ns.example.com/epcis/}sameFieldName=SameValueB
sensorElement
sensorReport
{https://ns.example.com/epcis/}sameFieldName=SameValueA
{
"@context": [
"https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
{
"example": "https://ns.example.com/epcis/"
}
],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate": "2023-08-25T15:00:00.1+01:00",
"epcisBody": {
"eventList": [
{
"type": "ObjectEvent",
"sensorElementList": [
{
"sensorReport": [
{
"type": "Temperature",
"value": 12.4,
"uom": "CEL",
"example:sameFieldName": "SameValueB"
}
]
},
{
"sensorReport": [
{
"type": "Temperature",
"value": 20.6,
"uom": "CEL",
"example:sameFieldName": "SameValueA"
}
]
}
]
}
]
}
}
ideally it should be ordered as follows:
sensorElement
sensorReport
{https://ns.example.com/epcis/}sameFieldName=SameValueA
sensorElement
sensorReport
{https://ns.example.com/epcis/}sameFieldName=SameValueB
hash generator fails for EPCIS events having a custom eventID
partial example:
...
"eventList": [
{
"type": "AggregationEvent",
"eventTime": "2013-06-08T14:58:56.591Z",
"eventTimeZoneOffset": "+02:00",
"eventID": "urn:uuid:5d3c82cc-3fb2-4b70-af4a-914f1f839c5b",
"parentID": "urn:epc:id:sscc:0614141.1234567890",
"childEPCs": [
"urn:epc:id:sgtin:0614141.107346.2017",
....
Dear @sboeckelmann ,
I presume that the (great) web tool residing on https://tools.openepcis.io/openepcis-ui/EventHash is based on this library.
If this holds true, I am happy to share the following observation. Then I passed the tool the following JSON-LD structure:
{ "@context": [ "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld", { "abc": "https://ns.abc.de/epcis/", "example": "http://ns.example.com/epcis/", "fgh": "https://ns.fgh.co.uk/epcis/", "schema": "https://schema.org/", "sdo": "https://schema.org/" } ], "type": "EPCISDocument", "schemaVersion": "2.0", "creationDate": "2005-07-11T11:30:47.0Z", "epcisBody": { "eventList": [ { "type": "ObjectEvent", "action": "OBSERVE", "bizStep": "receiving", "disposition": "in_progress", "epcList": [ "https://id.gs1.org/01/70614141123451/21/2018" ], "eventTime": "2005-04-04T20:33:31.116-06:00", "eventTimeZoneOffset": "-06:00", "readPoint": { "id": "urn:epc:id:sgln:0012345.11111.400" }, "bizLocation": { "id": "urn:epc:id:sgln:0012345.11111.0" }, "fgh:a-date": "2023-10-09", "example:myField": "Example of a vendor/user extension", "abc:a-integer": 2, "abc:z-integer": 1, "schema:award": "Order of Standards", "schema:mpn": "4711", "sdo:nsn": "4712" } ] } }
...the ordering works ALMOST flawlessly, with one exception. When you look at the extension fields further below, the field with 'http:' should in my POV be the first extension field as ":" comes before "s" in the UTF8 encoding table.
eventType=ObjectEvent
eventTime=2005-04-05T02:33:31.116Z
eventTimeZoneOffset=-06:00
epcList
epc=https://id.gs1.org/01/70614141123451/21/2018
action=OBSERVE
bizStep=https://ref.gs1.org/voc/Bizstep-receiving
disposition=https://ref.gs1.org/voc/Disp-in_progress
readPointid=https://id.gs1.org/414/0012345111112/254/400
bizLocationid=https://id.gs1.org/414/0012345111112/254/0
{https://ns.abc.de/epcis/}a-integer=2
{https://ns.abc.de/epcis/}z-integer=1
{http://ns.example.com/epcis/}myField=Example of a vendor/user extension
{https://ns.fgh.co.uk/epcis/}a-date=2023-10-09
{https://schema.org/}award=Order of Standards{https://schema.org/}mpn=4711
{https://schema.org/}nsn=4712
Would you agree to this?
Hope this helps.
Kind regards,
Ralph
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.