❯ rspec resource_sign_service_spec.rb
----| Hash test |----
{:a=>{:b=>"b", :c=>"c"}, :d=>"d"} vs {:d=>"d", :a=>{:c=>"c", :b=>"b"}}
+dIsjfhtier7LrkhmcNC9g== vs +dIsjfhtier7LrkhmcNC9g==
________________________________________________________________________________________
.----| Array test |----
[{:a=>{:b=>"b", :c=>"c"}, :d=>"d"}, {:d=>"d", :a=>{:c=>"c", :b=>"b"}}] vs [{:d=>"d", :a=>{:c=>"c", :b=>"b"}}, {:a=>{:b=>"b", :c=>"c"}, :d=>"d"}]
nGY1apVXDjKbeEtURBYe3A== vs nGY1apVXDjKbeEtURBYe3A==
________________________________________________________________________________________
.----| Json Text test |----
{"a":{"b":"b","c":"c"},"d":"d"} vs {"d":"d","a":{"c":"c","b":"b"}}
+dIsjfhtier7LrkhmcNC9g== vs +dIsjfhtier7LrkhmcNC9g==
________________________________________________________________________________________
.----| File binary test |----
/Users/wangha/Downloads/WechatIMG20.jpeg vs /Users/wangha/Downloads/WechatIMG20 copy.jpeg
x+yOEBqy4qnkkSbMqDm5Ug== vs x+yOEBqy4qnkkSbMqDm5Ug==
________________________________________________________________________________________
.
Finished in 0.05251 seconds (files took 0.25969 seconds to load)
4 examples, 0 failures
Created
September 28, 2021 10:00
-
-
Save mimosa/0879c321fb04bfbcc5a83f4bd92a114b to your computer and use it in GitHub Desktop.
Resource Sign Service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'openssl' unless defined?(OpenSSL::Digest) | |
require 'multi_json' unless defined?(MultiJson) | |
class ResourceSignService | |
def signature(content) | |
case content.class.name | |
when 'Hash' | |
arr = [] | |
content.each { |k, v| arr << "#{signature k}:#{signature v}" } | |
signature(arr) | |
when 'Array' | |
str = '' | |
content.sort.each { |v| str += signature(v) } | |
signature(str) | |
when 'String' | |
content = MultiJson.load(content) if %r{^(\{|\[)(.*)(\]|\})$}.match?(content) | |
content.is_a?(String) ? signature_str(content) : signature(content) | |
else | |
case true | |
when content.respond_to?(:read) | |
signature_io(content) | |
when content.respond_to?(:to_h) | |
signature(content.to_h) | |
when content.respond_to?(:as_json) | |
signature(content.as_json) | |
when content.respond_to?(:to_s) | |
signature(content.to_s) | |
else | |
content.class.to_s | |
end | |
end | |
end | |
private | |
CHUNK_SIZE = 1 * 1024 * 1024 # one MB | |
def signature_str(str) | |
OpenSSL::Digest::MD5.base64digest(str) | |
end | |
def signature_io(io, digest: nil, chunk_size: CHUNK_SIZE) | |
digest ||= OpenSSL::Digest::MD5.new | |
loop do | |
chunk = io.read(chunk_size) | |
break unless chunk | |
digest.update(chunk) | |
end | |
io.rewind | |
digest.base64digest | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'rspec/core' unless defined?(RSpec) | |
require './resource_sign_service' unless defined?(ResourceSignService) | |
RSpec.describe ResourceSignService do | |
let(:obj_a) { { a: { b: 'b', c: 'c' }, d: 'd' } } | |
let(:obj_b) { { d: 'd', a: { c: 'c', b: 'b' } } } | |
let(:arr_a) { [obj_a, obj_b] } | |
let(:arr_b) { [obj_b, obj_a] } | |
let(:json_a) { MultiJson.dump(obj_a) } | |
let(:json_b) { MultiJson.dump(obj_b) } | |
let(:file_path_a) { '/Users/wangha/Downloads/WechatIMG20.jpeg' } | |
let(:file_path_b) { '/Users/wangha/Downloads/WechatIMG20 copy.jpeg' } | |
describe 'match object with signature' do | |
it 'Hash' do | |
puts '----| Hash test |----' | |
puts "#{obj_a} vs #{obj_b}" | |
sign_a = subject.signature(obj_a) | |
sign_b = subject.signature(obj_b) | |
puts "#{sign_a} vs #{sign_b}" | |
puts '_' * 88 | |
expect(sign_a).to eq(sign_b) | |
end | |
it 'Array' do | |
puts '----| Array test |----' | |
puts "#{arr_a} vs #{arr_b}" | |
sign_a = subject.signature(arr_a) | |
sign_b = subject.signature(arr_b) | |
puts "#{sign_a} vs #{sign_b}" | |
puts '_' * 88 | |
expect(sign_a).to eq(sign_b) | |
end | |
it 'Json' do | |
puts '----| Json Text test |----' | |
puts "#{json_a} vs #{json_b}" | |
sign_a = subject.signature(json_a) | |
sign_b = subject.signature(json_b) | |
puts "#{sign_a} vs #{sign_b}" | |
puts '_' * 88 | |
expect(sign_a).to eq(sign_b) | |
end | |
xit 'File' do | |
puts '----| File binary test |----' | |
file_a = File.open(file_path_a, 'rb') | |
file_b = File.open(file_path_b, 'rb') | |
puts "#{file_path_a} vs #{file_path_b}" | |
sign_a = subject.signature(file_a) | |
sign_b = subject.signature(file_b) | |
puts "#{sign_a} vs #{sign_b}" | |
puts '_' * 88 | |
expect(sign_a).to eq(sign_b) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment