vchain_client 1.0.21 → 1.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vchain_client.rb +244 -240
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7db396f9ccc111daf170ae178b5dcc5a7dbe42a
4
- data.tar.gz: 74baca0c18f217d70c2a5b191f89911b9aa13533
3
+ metadata.gz: 65340391974700636c2d48e309226cae1e472797
4
+ data.tar.gz: 132f978b2d7e25377f9efdbc108e4f744a0d74a3
5
5
  SHA512:
6
- metadata.gz: d5043acbd5dbfb6b5848a606404d2e01ce8236c720f666b024adeca956425dd98717b9ec9669c4a991b2c595ab5e42be91efee201faa2c573b469744c143a377
7
- data.tar.gz: 83bfc37f83bc377462189da905466490a444d5f842bbc530bb47d022a23d0e92fcacb085a2ab1e42d4047aa9859f6e32c3835e37ee3f49c8cdb024670c00c71e
6
+ metadata.gz: 110cf09f708a3b23d8de059a9cbb9d14fbfbc48f7dbd4ef7a1f1a3097cb42345fc2b6ed62116fecd60553ad1f2e9a9779914991f0a9bc6602469a6205a4683f1
7
+ data.tar.gz: 959022c40a2975fb038ac62599bcdb320d4101d318fbe82565e3d470770171e8905fd9603356cd6836879b2bd8b717dc09ed90735d1d382967c9bff696bba78c
data/lib/vchain_client.rb CHANGED
@@ -37,10 +37,12 @@ module VChainClient
37
37
 
38
38
  def hash(arr)
39
39
  arr.each { |k, v|
40
- if k != "surname" && k != "given_names"
41
- arr[k] = Digest::SHA512.hexdigest(v.downcase)
42
- else
43
- arr[k] = Digest::SHA512.hexdigest(v)
40
+ if k != "names_parts"
41
+ if k != "surname" && k != "given_names"
42
+ arr[k] = Digest::SHA512.hexdigest(v.downcase)
43
+ else
44
+ arr[k] = Digest::SHA512.hexdigest(v)
45
+ end
44
46
  end
45
47
  }
46
48
  end
@@ -49,10 +51,12 @@ module VChainClient
49
51
  output = {}
50
52
 
51
53
  arr.each { |k, v|
52
- if k != "doc_hash"
53
- output[Digest::SHA512.hexdigest(k)] = Digest::SHA512.hexdigest(v)
54
- else
55
- output[k] = Digest::SHA512.hexdigest(v)
54
+ if k != "names_parts"
55
+ if k != "doc_hash"
56
+ output[Digest::SHA512.hexdigest(k)] = Digest::SHA512.hexdigest(v)
57
+ else
58
+ output[k] = Digest::SHA512.hexdigest(v)
59
+ end
56
60
  end
57
61
  }
58
62
 
@@ -220,7 +224,7 @@ module VChainClient
220
224
  def add_data_point(point_type, input, weight = 1)
221
225
 
222
226
  client_id = @config["client_id"]
223
- api_url = @config["api"]["url"] + "v0.1/addDataPoint/"
227
+ api_url = @config["api"]["url"] + "v0.2/addDataPoint/"
224
228
 
225
229
  time = Time.now.getutc
226
230
  timestamp = time.to_i
@@ -439,7 +443,7 @@ module VChainClient
439
443
 
440
444
  client_id = @config["client_id"]
441
445
 
442
- api_url = @config["api"]["url"] + "v0.1/check/";
446
+ api_url = @config["api"]["url"] + "v0.2/check/";
443
447
 
444
448
  document = input
445
449
 
@@ -455,10 +459,14 @@ module VChainClient
455
459
 
456
460
  document = self.cut(document)
457
461
 
462
+ names_index = {}
463
+
458
464
  if document["type"] == FIELD_TYPE_TRAVEL_DOCUMENT_HASHED
459
465
  document["names"] = []
460
466
  names.each { |name|
461
- document["names"].push(Digest::SHA512.hexdigest(name.downcase))
467
+ name_hash = Digest::SHA512.hexdigest(name.downcase)
468
+ names_index[name_hash] = name
469
+ document["names"].push(name_hash)
462
470
  }
463
471
  end
464
472
 
@@ -528,38 +536,6 @@ module VChainClient
528
536
 
529
537
  # success result
530
538
 
531
- if sent_document.key?("names")
532
-
533
- real_surname = ""
534
-
535
- real_given_name = ""
536
-
537
- if res.key?("names") && res["names"].is_a?(Hash)
538
-
539
- if res["names"].key?("given_names")
540
- sep = "";
541
- res["names"]["given_names"].each { |found_given_name|
542
- real_given_name += sep + found_given_name
543
- sep = " "
544
- }
545
- end
546
-
547
- if res["names"].key?("surname")
548
- sep = "";
549
- res["names"]["surname"].each { |found_surname|
550
- real_surname += sep + found_surname
551
- sep = " "
552
- }
553
- end
554
-
555
- end
556
-
557
- sent_document["given_names"] = Digest::SHA512.hexdigest(real_given_name)
558
- sent_document["surname"] = Digest::SHA512.hexdigest(real_surname)
559
-
560
- sent_document.delete("names")
561
- end
562
-
563
539
  validated_data_points = self.validate_data_points(res["data_points"], res["docs"])
564
540
 
565
541
  if validated_data_points.length == 0
@@ -573,289 +549,317 @@ module VChainClient
573
549
  }
574
550
 
575
551
  return {
576
- "status" => "success",
577
- "validated" => result
552
+ "status" => "success",
553
+ "validated" => result,
554
+ "hashed_input" => sent_document
578
555
  }
579
556
 
580
557
  end
581
558
 
559
+ #
582
560
  # analyse
561
+ #
583
562
 
584
- new_res_docs = []
585
-
586
- res_docs_index = {}
587
-
588
- # cut and index
589
- res["docs"].each { |res_doc|
590
-
591
- full_doc_hash = self.get_doc_hash(res_doc)
592
-
593
- play_doc = {}
594
- res_doc.each { |field, value|
595
- if sent_document.key?(field)
596
- play_doc[field] = value
597
- end
598
- }
599
-
600
- res_doc_credentials_hash = self.get_credentials_hash(play_doc)
601
-
602
- if !res_docs_index.key?(res_doc_credentials_hash)
603
- res_docs_index[res_doc_credentials_hash] = []
604
- end
605
-
606
- play_doc["doc_hash"] = self.get_doc_hash(play_doc)
607
-
608
- play_doc["full_doc_hash"] = full_doc_hash
609
-
610
- res_docs_index[res_doc_credentials_hash].push(play_doc)
611
-
612
- new_res_docs.push(play_doc)
613
- }
614
-
615
- res["docs"] = new_res_docs
616
-
563
+ sent_type_credentials_fields = self.get_credentials_fields(sent_document["type"])
617
564
 
618
- sent_doc_hash = self.get_doc_hash(sent_document)
619
565
 
620
- sent_credentials_hash = self.get_credentials_hash(sent_document)
566
+ # 1. cut non-input fields, rebuild doc_hashes
567
+ # 2. build vectors out of cut documents
621
568
 
622
- hashed_sent_doc = self.full_hash(sent_document)
569
+ cut_res_docs = []
623
570
 
624
- hashed_sent_doc_hash = Digest::SHA512.hexdigest(sent_doc_hash)
571
+ vectors = []
625
572
 
626
- # trying to find exact match by doc_hash
627
-
628
- if validated_data_points.key?(hashed_sent_doc_hash)
629
-
630
- # exact match found by doc_hash
631
-
632
- result = {}
633
-
634
- exact_match = validated_data_points[hashed_sent_doc_hash]
635
-
636
- sent_document.each { |field, value|
637
-
638
- hashed_field = Digest::SHA512.hexdigest(field)
573
+ res["docs"].each { |res_doc|
639
574
 
640
- if exact_match.key?(hashed_field)
575
+ cut_doc = {}
576
+ vector = {}
641
577
 
642
- result[field] = exact_match[hashed_field]
578
+ names_parts = {}
579
+ if res_doc.key?("names_parts")
580
+ names_parts = res_doc["names_parts"]
643
581
 
644
- else
582
+ res_doc.delete("names_parts")
583
+ end
645
584
 
646
- result[field] = 0
585
+ full_doc_hash = self.get_doc_hash(res_doc)
647
586
 
587
+ res_doc.each { |res_doc_field, res_doc_value|
588
+ if sent_document.key?(res_doc_field) || sent_type_credentials_fields.include?(res_doc_field)
589
+ cut_doc[res_doc_field] = res_doc_value
590
+
591
+ vector[Digest::SHA512.hexdigest(res_doc_field)] = [res_doc_value, res_doc_field, 0]
648
592
  end
649
-
650
- }
651
-
652
- return {
653
- "status" => "success",
654
- "validated" => result
655
593
  }
656
594
 
657
- else
658
-
659
- # search by credentials_hash
660
-
661
- found_docs = []
662
- if res_docs_index.key?(sent_credentials_hash)
663
- found_docs = res_docs_index[sent_credentials_hash]
664
- end
665
-
666
- if found_docs.length > 0
595
+ cut_doc["doc_hash"] = self.get_doc_hash(cut_doc)
667
596
 
668
- # matches found by credentials
597
+ cut_doc["full_doc_hash"] = full_doc_hash
669
598
 
670
- result = {}
599
+ hashed_full_doc_hash = Digest::SHA512.hexdigest(full_doc_hash);
671
600
 
672
- possible_mistakes = []
601
+ if validated_data_points.key?(hashed_full_doc_hash)
602
+ data_points = validated_data_points[hashed_full_doc_hash]
673
603
 
674
- cred_fields = self.get_credentials_fields(sent_document["type"]);
604
+ data_points.each { |data_point_field, data_point_value|
605
+ if vector.key?(data_point_field)
606
+ vector[data_point_field][2] += data_point_value
607
+ end
608
+ }
609
+ end
675
610
 
676
- non_cred_fields_index = {}
611
+ if !names_parts.empty?
612
+ cut_doc["names_parts"] = names_parts
613
+ vector["names_parts"] = names_parts
614
+ end
677
615
 
678
- found_docs.each { |cred_doc|
616
+ vectors.push(vector)
679
617
 
680
- cred_doc_hash = cred_doc["full_doc_hash"]#self.get_doc_hash(cred_doc)
681
- cred_doc_hash = Digest::SHA512.hexdigest(cred_doc_hash)
618
+ cut_res_docs.push(cut_doc)
619
+ }
682
620
 
683
- cred_doc_exact_match = validated_data_points[cred_doc_hash]
621
+ res["docs"] = cut_res_docs
684
622
 
685
- # fill credential fields
686
- cred_fields.each { |cred_field|
687
623
 
688
- cred_field_hashed = Digest::SHA512.hexdigest(cred_field)
624
+ # 3. combine vectors part 1 - marking => absorb smaller, merge equal
625
+ for i in 0..(vectors.length - 1)
689
626
 
690
- if !result.key?(cred_field)
691
- result[cred_field] = 0
692
- end
627
+ vector_i = vectors[i]
628
+
629
+ for j in i+1..(vectors.length - 1)
693
630
 
694
- if cred_doc_exact_match.key?(cred_field_hashed)
695
- result[cred_field] += cred_doc_exact_match[cred_field_hashed]
696
- end
631
+ if j >= vectors.length
632
+ break
633
+ end
697
634
 
698
- }
635
+ vector_j = vectors[j]
699
636
 
700
- # fill non credential fields
701
- cred_doc.each { |field, value|
702
-
703
- if !cred_fields.include?(field) && field != "doc_hash"
637
+ i_is_less_j = false
638
+ j_is_less_i = false
704
639
 
705
- non_cred_field_hashed = Digest::SHA512.hexdigest(field)
706
-
707
- if !non_cred_fields_index.key?(field)
708
- non_cred_fields_index[field] = {}
709
- end
640
+ need_to_combine = true
710
641
 
711
- if !non_cred_fields_index[field].key?(value)
712
- non_cred_fields_index[field][value] = 0
642
+ vector_i.each { |vector_i_hashed_field, vector_i_values|
643
+ if vector_i_hashed_field != "names_parts" && vector_i_hashed_field != "resolutions"
644
+ if !vector_j.key?(vector_i_hashed_field)
645
+ j_is_less_i = true
646
+ else
647
+ vector_j_values = vector_j[vector_i_hashed_field]
648
+ if vector_i_values[0] != vector_j_values[0]
649
+ need_to_combine = false
650
+ break
713
651
  end
652
+ end
653
+ end
654
+ }
714
655
 
715
- if cred_doc_exact_match.key?(non_cred_field_hashed)
716
- non_cred_fields_index[field][value] += cred_doc_exact_match[non_cred_field_hashed]
656
+ vector_j.each { |vector_j_hashed_field, vector_j_values|
657
+ if vector_j_hashed_field != "names_parts" && vector_j_hashed_field != "resolutions"
658
+ if !vector_i.key?(vector_j_hashed_field)
659
+ i_is_less_j = true
660
+ else
661
+ vector_i_values = vector_i[vector_j_hashed_field]
662
+ if vector_j_values[0] != vector_i_values[0]
663
+ need_to_combine = false
664
+ break
717
665
  end
718
-
719
666
  end
720
-
721
- }
722
-
667
+ end
723
668
  }
724
669
 
725
- non_cred_fields_index.each { |field, values|
726
-
727
- if sent_document.key?(field)
670
+ if need_to_combine
671
+ if i_is_less_j && j_is_less_i
672
+ # differs, no need to combine
728
673
 
729
- if values.length == 1
674
+ elsif i_is_less_j && !j_is_less_i
675
+ # combine i to j
676
+ if !vectors[i].key?("resolutions")
677
+ vectors[i]["resolutions"] = []
678
+ end
679
+ if !vectors[j].key?("resolutions")
680
+ vectors[j]["resolutions"] = []
681
+ end
682
+ vectors[i]["resolutions"].push(["combine_to", j])
683
+ vectors[j]["resolutions"].push(["absorb", i])
730
684
 
731
- values.take(1).each { |value, validated_count|
732
- if value == sent_document[field]
733
- result[field] = validated_count
734
- else
735
- possible_mistakes.push(field)
736
- end
737
- }
685
+ elsif !i_is_less_j && j_is_less_i
686
+ # combine j to i
687
+ if !vectors[i].key?("resolutions")
688
+ vectors[i]["resolutions"] = []
689
+ end
690
+ if !vectors[j].key?("resolutions")
691
+ vectors[j]["resolutions"] = []
692
+ end
693
+ vectors[j]["resolutions"].push(["combine_to", i])
694
+ vectors[i]["resolutions"].push(["absorb", j])
738
695
 
739
- else
740
- possible_mistakes.push(field)
696
+ else
697
+ # equals, combine j to i and delete j
698
+ if !vectors[i].key?("resolutions")
699
+ vectors[i]["resolutions"] = []
741
700
  end
701
+ if !vectors[j].key?("resolutions")
702
+ vectors[j]["resolutions"] = []
703
+ end
704
+ vectors[j]["resolutions"].push(["combine_to", i])
705
+ vectors[i]["resolutions"].push(["absorb", j])
742
706
 
743
707
  end
708
+ end
709
+ end
710
+ end
744
711
 
745
- }
746
-
747
- return {
748
- "status" => "success",
749
- "possible_mistakes" => possible_mistakes,
750
- "validated" => result
751
- }
752
-
753
- else
754
-
755
- # search for possible errors in credentials
712
+ # 4. combine vectors part 2 - resolutions execution => absorb smaller, merge equal
713
+ vectors_to_remove = []
756
714
 
757
- similar_sets = self.get_similar_credential_sets(sent_document["type"])
715
+ for i in 0..(vectors.length-1)
758
716
 
759
- result = {}
760
- possible_mistakes = []
717
+ vector_i = vectors[i]
761
718
 
762
- other_fields_index = {}
719
+ if vector_i.key?("resolutions")
763
720
 
764
- similar_sets.each { |lookup_set|
721
+ need_to_delete = false
765
722
 
766
- lookup_set_match_found = false
723
+ vector_i["resolutions"].each { |resolution|
724
+
725
+ resolution_type = resolution[0]
767
726
 
768
- res["docs"].each { |res_doc|
727
+ if resolution_type == "combine_to"
728
+
729
+ vector_i["resolutions"].each { |resolution_b|
730
+
731
+ if resolution_b[0] == "absorb"
732
+ if !vectors[resolution[1]].key?("resolutions")
733
+ vectors[resolution[1]]["resolutions"] = []
734
+ end
769
735
 
770
- is_matching = true
736
+ # check for dublicates
737
+ need_to_add = true
771
738
 
772
- lookup_set.each { |lookup_field|
773
- sent_doc_val = sent_document[lookup_field]
774
- res_doc_val = res_doc[lookup_field]
739
+ vectors[resolution[1]]["resolutions"].each { |resolution_c|
740
+ if resolution_c[0] == resolution_b[0] && resolution_c[1] == resolution_b[1]
741
+ need_to_add = false
742
+ break
743
+ end
744
+ }
775
745
 
776
- if sent_doc_val != res_doc_val
777
- is_matching = false
778
- break
746
+ if need_to_add
747
+ vectors[resolution[1]]["resolutions"].push(resolution_b)
748
+ end
779
749
  end
780
750
  }
781
751
 
782
- if is_matching
783
- matching_doc_hash = self.get_doc_hash(res_doc)
784
- matching_doc_hash = Digest::SHA512.hexdigest(matching_doc_hash)
785
-
786
- matching_exact_match = validated_data_points[matching_doc_hash]
787
-
788
- lookup_set.each { |lookup_field|
752
+ need_to_delete = true
753
+ end
754
+ }
789
755
 
790
- lookup_field_hashed = Digest::SHA512.hexdigest(lookup_field)
756
+ if need_to_delete
757
+ vectors_to_remove.push(i)
758
+ end
759
+ end
760
+ end
791
761
 
792
- result[lookup_field] = matching_exact_match[lookup_field_hashed]
793
- }
762
+ for i in 0..(vectors.length - 1)
794
763
 
795
- res_doc.each { |field, value|
796
-
797
- if !lookup_set.include?(field) && field != "doc_hash"
764
+ vector_i = vectors[i]
798
765
 
799
- other_field_hashed = Digest::SHA512.hexdigest(field)
800
-
801
- if !other_fields_index.key?(field)
802
- other_fields_index[field] = {}
803
- end
766
+ if vector_i.key?("resolutions")
767
+ if !vectors_to_remove.include?(i)
804
768
 
805
- if !other_fields_index[field].key?(value)
806
- other_fields_index[field][value] = 0
807
- end
769
+ vector_i["resolutions"].each { |resolution|
808
770
 
809
- if matching_exact_match.key?(other_field_hashed)
810
- other_fields_index[field][value] += matching_exact_match[other_field_hashed]
811
- end
771
+ if resolution[0] == "absorb"
772
+ vector_j = vectors[resolution[1]]
812
773
 
774
+ vector_j.each { |vector_j_hashed_field, vector_j_values|
775
+ if vector_j_hashed_field != "names_parts" && vector_j_hashed_field != "resolutions"
776
+ vectors[i][vector_j_hashed_field][2] += vector_j_values[2]
813
777
  end
814
-
815
778
  }
816
-
817
- lookup_set_match_found = true
818
779
  end
780
+
819
781
  }
820
782
 
821
- if lookup_set_match_found
822
- break
823
- end
783
+ vectors[i].delete("resolutions")
824
784
 
825
- }
785
+ end
786
+ end
787
+ end
826
788
 
827
- other_fields_index.each { |field, values|
789
+ # remove marked vectors
790
+ vectors_removed_number = 0
791
+ vectors_to_remove.each { |index|
792
+ vectors.delete_at(index - vectors_removed_number)
793
+ vectors_removed_number += 1
794
+ }
828
795
 
829
- if sent_document.key?(field)
796
+ # prepare for output
830
797
 
831
- if values.length == 1
798
+ vectors_fliped = []
832
799
 
833
- values.take(1).each { |value, validated_count|
834
- if value == sent_document[field]
835
- result[field] = validated_count
836
- else
837
- possible_mistakes.push(field)
838
- end
839
- }
800
+ for i in 0..(vectors.length - 1)
840
801
 
841
- else
842
- possible_mistakes.push(field)
843
- end
802
+ vector_fliped = {}
844
803
 
845
- end
804
+ vectors[i].each { |hashed_vector_field, vector_values|
846
805
 
847
- }
806
+ if hashed_vector_field != "names_parts"
807
+ val = "same"
808
+ if sent_document[vector_values[1]] != vector_values[0]
809
+ val = "different"
810
+ end
811
+ vector_fliped[vector_values[1]] = [val, vector_values[2]]
812
+ else
813
+ vector_fliped[hashed_vector_field] = vector_values
814
+ end
815
+ }
848
816
 
849
- return {
850
- "status" => "success",
851
- "possible_mistakes" => possible_mistakes,
852
- "validated" => result
853
- }
817
+ vector_raw_surname = ""
818
+ if vector_fliped.key?("names_parts")
819
+ if vector_fliped["names_parts"].key?("surname")
820
+ sep = ""
821
+ vector_fliped["names_parts"]["surname"].each { |surname_part|
822
+ vector_raw_surname += sep + names_index[surname_part]
823
+ sep = " "
824
+ }
825
+ else
826
+ vector_raw_surname = "different"
827
+ end
828
+ else
829
+ vector_raw_surname = "different"
830
+ end
854
831
 
832
+ vector_raw_given_names = ""
833
+ if vector_fliped.key?("names_parts")
834
+ if vector_fliped["names_parts"].key?("given_names")
835
+ sep = ""
836
+ vector_fliped["names_parts"]["given_names"].each { |given_names_part|
837
+ vector_raw_given_names += sep + names_index[given_names_part]
838
+ sep = " "
839
+ }
840
+ else
841
+ vector_raw_given_names = "different"
842
+ end
843
+ else
844
+ vector_raw_given_names = "different"
855
845
  end
856
846
 
847
+ vector_fliped["surname"] = [vector_raw_surname, vector_fliped["surname"][1]]
848
+ vector_fliped["given_names"] = [vector_raw_given_names, vector_fliped["given_names"][1]]
849
+
850
+ vector_fliped.delete("names_parts")
851
+
852
+ vectors_fliped.push(vector_fliped)
853
+
857
854
  end
858
855
 
856
+ # result output
857
+
858
+ return {
859
+ "status" => "success",
860
+ "vectors" => vectors_fliped
861
+ }
862
+
859
863
  end
860
864
  end
861
865
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vchain_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.21
4
+ version: 1.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksandr Gorelik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-27 00:00:00.000000000 Z
11
+ date: 2017-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: log4r