How to reverse algorithm of id => key conversion? - algorithm

I have some set of pairs (id,key).
Set 1:
id=12877074 key=2ac90cf4
id=12877104 key=7d2ab9ab
id=12877134 key=11b2ec50
id=12877201 key=c428eb88
id=12890200 key=d8ad8b8c
id=12901142 key=f04896ba
id=12913608 key=934d4ad5
Set 2:
id=1168056109 key=L949f50be7a
id=1243780701 key=L254ecc879b
id=1247980634 key=M788bd17c10
id=1300610428 key=M5fa760c4a0
id=1317428974 key=Md2e645bac9
Is it possible to detemine how can I obtain key from id?

Related

How to hash by choosing the key and the string value with Ruby

I'm traying to hash urls with Ruby but I had some problems the size of my urls differs from one url to another, hence my hash key doesn't give me the right result.
2 examples of my urls
url1="Services/tech_name/prise/name_Prise/service_name/sites/xxxx/yyyy/devices/AAAA/wan/16170515?startDate=2021-01-18T23:00: 00.000Z&endDate=2021-01-19T08:22:42.000Z& timeProfile=1&tz=CET"
url2="Services/tech_name/prise/name_Prise/service_name/sites/xxxx/yyyy/devices/AAAA/BBBB/wan/1617051?startDate=2021-01-18T23:00: 00.000Z&endDate=2021-01-19T08:22:42.000Z& timeProfile=1&tz=CET"
Example of my code to hash url1:
url1="Services/tech_name/prise/name_Prise/service_name/sites/xxxx/yyyy/devices/AAAA/wan/16170515?startDate=2021-01-18T23:00: 00.000Z&endDate=2021-01-19T08:22:42.000Z& timeProfile=1&tz=CET"
spliturl=my_url.gsub("?","/")
url=spliturl.split("/")
if !url.count.even?
url.push(nil)
h=Hash[*url]
puts h
end
My result:
{"Services"=>"name_services", "prise"=>"name_prise", "tech"=>"sites", "xxxx"=>"yyyy", "devices"=>"AAAA", "wan"=>"16170515", "startDate=2021-01-18T23:00:00.000Z&endDate=2021-01-19T08:22:42.000Z&timeProfile=1&tz=CET"=>nil}
The "sites" has become a value and the "sites" value has become a key !!
{"tech"=>"sites", "xxxx"=>"yyyy", "devices"=>"AAAA", "wan"=>"16170515"}
But the result I would like to have from url1:
{"sites" => "xxxx/yyyy", "devices" => "AAAA", "wan" => "16170515"}
and from url2:
{"sites" => "xxxx/yyyy", "devices" => "AAAA/BBBB", "wan" => "1617051"}
I have one idea how you could solve the problem:
result = url1.match /\/sites\/(?<sites>.*)\/devices\/(?<devices>.*)\/wan\/(?<wan>.*)\?/
Then to get values from results:
result[:sites] => "xxxx/yyyy"
result[:devices] => "AAAA"
result[:wan] => "16170515"

Parsing XML message

I'm attempting to parse the following XML:
<marketstat><type id="18">
<buy><volume>33000000</volume><avg>40.53</avg><max>65.57</max><min>6.55</min><stddev>26.61</stddev><median>58.56</median><percentile>65.57</percentile></buy>
<sell><volume>494489</volume><avg>69.47</avg><max>69.47</max><min>69.47</min><stddev>0.00</stddev><median>69.47</median><percentile>69.47</percentile></sell>
<all><volume>33494489</volume><avg>40.96</avg><max>69.47</max><min>6.55</min><stddev>26.77</stddev><median>58.56</median><percentile>6.55</percentile></all>
</type><type id="19">
<buy><volume>270000</volume><avg>1707.31</avg><max>3549.38</max><min>239.74</min><stddev>1554.26</stddev><median>239.75</median><percentile>3549.34</percentile></buy>
<sell><volume>48599</volume><avg>24930.45</avg><max>29869.95</max><min>5200.00</min><stddev>9875.66</stddev><median>29869.93</median><percentile>5232.20</percentile></sell>
<all><volume>280926</volume><avg>1957.07</avg><max>10750.00</max><min>239.74</min><stddev>3352.87</stddev><median>1874.31</median><percentile>239.74</percentile></all>
</type></marketstat>
</evec_api>
The pieces of information that I want to retrieve are the minimum sell and maximum buy values, associated with the ID, found here: <sell><min>69.47</min></sell>.
I'm currently using the following to get the XML: marketData = Nokogiri::XML(open(api))
Use xpath to pull out the nodes of interest, then convert them to Floats and pick the value you want. The path to your minimum sell node is /marketstat/type/sell/min, or if you want to use shorthand, // says "anywhere in the document", so you can specify just //sell/min to get all of the minimum sell nodes and //buy/max to get all of the maximum buys.
sells = market_data.xpath('//sell/min').map(&:content).map(&:to_f)
buys = market_data.xpath('//buy/max').map(&:content).map(&:to_f)
puts sells.min, buys.max
The following will print the ID and its corresponding min/max:
marketData = Nokogiri::XML(open(api))
marketData.xpath("//type").each do |i|
puts "#{i.attr('id')}: #{i.xpath('.//max').map {|j| j.text.to_f}.max}"
puts "#{i.attr('id')}: #{i.xpath('.//min').map {|j| j.text.to_f}.min}"
end
Output:
18: 69.47
18: 6.55
19: 29869.95
19: 239.74

How do I refactor OpenSSL pkcs5_keyivgen in ruby?

I have been using the following code in my app for the past year and have 200k record using this code:
options = { :algorithm => 'aes-256-cbc', :value => "changethis", :key => "secretkey" }
cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
cipher.send(:encrypt)
cipher.pkcs5_keyivgen(options[:key])
result = cipher.update(options[:value])
result << cipher.final
# => "x\xED\x14s\xFD\x0E\x97\xC5\x996[M\x1E\x94\xDEI"
I am required (by business) to refactor the pkcs5_keyivgen part, to do it correctly: For example,
options = { :algorithm => 'aes-256-cbc', :value => "changethis", :key => "secretkey" }
cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
cipher.send(:encrypt)
cipher.key = '' # ??? 1) How does pkcs5_keyivgen in above code generate key, or does it just use my options[:key]
cipher.iv = '' # ??? 2) How does pkcs5_keyivgen in above code generate iv
result = cipher.update(options[:value])
result << cipher.final
I have to figure out how pkcs5_keyivgen sets key and iv. ideas here? We are using ruby-1.9.3-p286 and encryptor-1.1.3
I saw this question and this question, but they haven't help me solve the problem.
Was trying to solve this problem, but I think there is no easy solution or i just can't see one). Pkcs5_keyivgen() is deprecated and implements non-standard pass key derivation for AES 256.
From this docs and this source code
Pkcs5_keyivgen (pass, SALT = nil, num = 2048, digest = "MD5") -> nil
Generates some key and IV from salt and pass. No salt in your case. Generation method is defined in v1.5 PKCS #5 (deprecated)
So you are looking for "Password Based Key Derivation Function". PBKDF1
Pkcs5_keyivgen() function calls EVP_BytesToKey() from Openssl and EVP_BytesToKey() generates key bytes for larger key size in a non-standard way
So MD5 generates hash of size EVP_MAX_MD_SIZE (16 + 20) // 16 for MD5
But AES key(32) + IV(16) sizes > EVP_MAX_MD_SIZE, so AES 256 will need multiple hashes to generate random key and IV. Here is source code of algorithm in C
And here is nice pseudo-code explanation of the EVP_BytesToKey()
If you really want to re-implement PBKDF1 here is also RTC2898 standard for PBKDF1
But i don't think that it is a good idea to implement crypto yourself

Extract fields out of a ruby hash with special chars

I'm working to turn a pdf signature visible, using origami.pdf, and meanwhile I noticed that my signature is an hash, and so I try to capture fields like "Location", "Reason", "Date", "ContactInfo".
{/Type=>/Sig, /Contents=>"0\x82\a\xAE\x06\t*\x86H\x86\xF7\r\x01\a\x02\xA0\x82\a\
x9F0\x82\a\x9B\x02\x01\x011\v0\t\x06\x05+\x0E\x03\x02\x1A\x05\x000#\x06\t*\x86H\
x86\xF7\r\x01\a\x01\xA0\x16\x04\x14\xEF8uEn1#\x11M\x95\xE4\xD7\x9C\xFE(\xCF\xB7\
x92\x01\xC2\xA0\x82\x05\x970\x82\x05\x930\x82\x04{\xA0\x03\x02\x01\x02\x02\x04Bo
\x93\x8C0\r\x06\t*\x86H\x86\xF7\r\x01\x01\x05\x05\x000>1\v0\t\x06\x03U\x04\x06\x
13\x02pt1\x150\x13\x06\x03U\x04\n\x13\fMULTICERT-CA1\x180\x16\x06\x03U\x04\x03\x
13\x0FMULTICERT-CA 020\x1E\x17\r130320170147Z\x17\r140320164736Z0\x81\xA51\v0\t\
x06\x03U\x04\x06\x13\x02PT1\x150\x13\x06\x03U\x04\n\x13\fMULTICERT-CA1\x160\x14\
x06\x03U\x04\v\x13\rCERTIPOR - RA1\x120\x10\x06\x03U\x04\v\x13\tCorporate1 0\x1E
\x06\x03U\x04\v\x13\x17ESCRITA INTELIGENTE LDA1\x180\x16\x06\x03U\x04\v\x13\x0FW
eb Application1\x170\x15\x06\x03U\x04\x03\x13\x0ERECIBOS ONLINE0\x81\x9F0\r\x06\
t*\x86H\x86\xF7\r\x01\x01\x01\x05\x00\x03\x81\x8D\x000\x81\x89\x02\x81\x81\x00\x
AC\xCE\xA4\x06\x901\xB5x\x89lE\rw\xC8<\x13\xDDu\xC6h\xBF'b6\x8D\xB0\xA0\xB1Y\e\x
18\x00\xE5\x8C\x1A\xCD\xBB%\xDA\x15P\x1A\xF91\xF9\xF6\xBA\xE0\xF8\xF6LH\x16\x86\
xE9Y\xDE\x00Z\xEC\x82\xB3=\r2fP7\xD1\x8B\xF3k\xF7|MVb\fB\xFB\xBA\x92\xD3\xFF9\x7
F\x9D\x83w\xFE\xAB\xBA\x93G\x8F\xCE\xF0\t!d\x83\xD3F\xAC\xCCv\xCA\x10\xC9\xB8e;\
x80\xB8\xF6\xEBI\xBD\x93\x89zC\xDF\x06-\r\x9E\xD3\x02\x03\x01\x00\x01\xA3\x82\x0
2\xB30\x82\x02\xAF0\v\x06\x03U\x1D\x0F\x04\x04\x03\x02\x03\xF808\x06\b+\x06\x01\
x05\x05\a\x01\x01\x04,0*0(\x06\b+\x06\x01\x05\x05\a0\x01\x86\x1Chttp://ocsp.mult
icert.com/ca0\x81\xE0\x06\x03U\x1D \x04\x81\xD80\x81\xD50M\x06\t+\x06\x01\x04\x0
1\xB0<\n\x020#0>\x06\b+\x06\x01\x05\x05\a\x02\x01\x162http://www.multicert.com/c
ps/multicert-ca-cps.html0\x81\x83\x06\v+\x06\x01\x04\x01\xB0<\n\x02\x88\x060t0r\
x06\b+\x06\x01\x05\x05\a\x02\x020f\x1Ed\x00h\x00t\x00t\x00p\x00:\x00/\x00/\x00w\
x00w\x00w\x00.\x00m\x00u\x00l\x00t\x00i\x00c\x00e\x00r\x00t\x00.\x00c\x00o\x00m\
x00/\x00c\x00p\x00/\x00m\x00u\x00l\x00t\x00i\x00c\x00e\x00r\x00t\x00-\x00c\x00a\
x00-\x001\x000\x003\x000\x00.\x00h\x00t\x00m\x00l0\x11\x06\t`\x86H\x01\x86\xF8B\
x01\x01\x04\x04\x03\x02\x04\xB00 \x06\x03U\x1D\x11\x04\x190\x17\x81\x15info#reci
bosonline.pt0\x82\x01\x01\x06\x03U\x1D\x1F\x04\x81\xF90\x81\xF60\x81\x9A\xA0\x81
\x97\xA0\x81\x94\x86/http://www.multicert.com/ca/multicert-ca-02.crl\x86aldap://
ldap.multicert.com/cn=MULTICERT-CA%2002,o=MULTICERT-CA,c=PT?certificateRevocatio
nList?base0W\xA0U\xA0S\xA4Q0O1\v0\t\x06\x03U\x04\x06\x13\x02pt1\x150\x13\x06\x03
U\x04\n\x13\fMULTICERT-CA1\x180\x16\x06\x03U\x04\x03\x13\x0FMULTICERT-CA 021\x0F
0\r\x06\x03U\x04\x03\x13\x06CRL2950\x1F\x06\x03U\x1D#\x04\x180\x16\x80\x14\x1D\x
C3\xB9\x88\xA5\x18\xBE`\xA7,\xA6c\xCAf*\xFC\f'\xC1\xBD0\x1D\x06\x03U\x1D\x0E\x04
\x16\x04\x14\x06\xD8\x1Fr6a\x9E\xEB\x176\x9C)\x9E-t\xFF\xD080\x190\t\x06\x03U\x1
D\x13\x04\x020\x000\r\x06\t*\x86H\x86\xF7\r\x01\x01\x05\x05\x00\x03\x82\x01\x01\
x00AQ\x1F\xCD\\ua\x98\e\rT2kW\xF7\xB8|CZ\xAC\xB7\xA2\x96(\bv\x83\x13\x89*\xB1#r7
\xE9WW{\x87T\x14\xDE\x81\nA2?\x9E\nv\x8E\x9A\xC4\\\x0Ff\xAE\t<2\xC1\x14S\xC6F?\x
85o\xEFb\xE2x!\x13M\xD0\x9Fu \x80\x00\x04\x0E\x89\xA8\x14\xE60\x96#\xC5\xD0Ac\xC
0<\xFD\xE31S\x90\x8A\xC3\xDF\xCA[\x1Cf\xC3\xDC\xB8\x96D\xA3\x03\x0F\xE7\x94\xD5\
v\xD2U\xD3\x96SZz\xF2g\xC3\xA58\x14{\x93q\xD0_#\xD8\xCAH\x1A\xEB\xC7\xD7\xA7\xD9
|.\x7F\xB5\xABI\xC4\xE4UNH\x00d\x8B\xC7k\x1A\xF5a*\x1D\x93a\xD1r\bNpi\t(\xA9\x11
\xFC \x983\xC5\x06!\x9C\xF1\x86\xB6P{Y\x9EL\x0FB\xF3\xBF#\xC2\xB8\xF0\xA0x\xD0\x
1D\x9B\xF5\xFDGF\xD9rS\xEEO\xE8\xF4rH\x9B=\xC2opr\xC6Xr\x18\x82[\xB3\x06\x10t\xB
9\xC2#\xF8\x92\x8D6\xFE\xFC\x0Fp\x88\x97u,\xD9F1\x82\x01\xC70\x82\x01\xC3\x02\x0
1\x010F0>1\v0\t\x06\x03U\x04\x06\x13\x02pt1\x150\x13\x06\x03U\x04\n\x13\fMULTICE
RT-CA1\x180\x16\x06\x03U\x04\x03\x13\x0FMULTICERT-CA 02\x02\x04Bo\x93\x8C0\t\x06
\x05+\x0E\x03\x02\x1A\x05\x00\xA0\x81\xD80\x18\x06\t*\x86H\x86\xF7\r\x01\t\x031\
v\x06\t*\x86H\x86\xF7\r\x01\a\x010\x1C\x06\t*\x86H\x86\xF7\r\x01\t\x051\x0F\x17\
r130329223127Z0#\x06\t*\x86H\x86\xF7\r\x01\t\x041\x16\x04\x14\x93\xD9l\xBD68\xDB
*M\xADY\xF8\x8F<\x8E\x94m\xACS\xAE0y\x06\t*\x86H\x86\xF7\r\x01\t\x0F1l0j0\v\x06\
t`\x86H\x01e\x03\x04\x01*0\v\x06\t`\x86H\x01e\x03\x04\x01\x160\v\x06\t`\x86H\x01
e\x03\x04\x01\x020\n\x06\b*\x86H\x86\xF7\r\x03\a0\x0E\x06\b*\x86H\x86\xF7\r\x03\
x02\x02\x02\x00\x800\r\x06\b*\x86H\x86\xF7\r\x03\x02\x02\x01#0\a\x06\x05+\x0E\x0
3\x02\a0\r\x06\b*\x86H\x86\xF7\r\x03\x02\x02\x01(0\r\x06\t*\x86H\x86\xF7\r\x01\x
01\x01\x05\x00\x04\x81\x803]\xBC\xA2\xC5\x0F&\r\x94\x96\xD5\xBD\xF2\x96\xB3\x86\
x9D\x01\xA3{5\xEC\xA5\xEC\x8B=\r\xD7%w0o\x9C\x7F\v\x17YX\x80\xAF\x1A\x8F\x1E\xBB
e\xBCp4\xF7\x80\x89b&?\xCE<\xCC\x8D\xFE\xEFK\x86\x0F\xD8Q\xFFU\x04\x11E\t\xED\xC
9=WF\x93\x10w\xC6g\xD4\e`\xE5\xB5{Ax~%\xE9\x92\xF5\x01\x19\xCDS\xE1|%\"\xB2\xC6\
x107\xE9\xF7M\xD7\xA3\x11MJ\xAF\x03\x0F\xFF\x8D:s\x84g\xB6\xD5o\xAF\xB0\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00", /Filter=>/Adobe.PPKMS, /SubFilter=>/adbe.pkcs7.sha1, /
ByteRange=>[0, 12883, 17081, 1098], /Location=>"Portugal", /ContactInfo=>"email#email.com", /Reason=>"Proof of Concept", /M=>"D:20130329223127Z00'00", /P
rop_Build=>{/Filter=>{/Name=>/Adobe.PPKMS, /R=>131101, /Date=>"2013-03-29 22:31:
27 +0000"}, /SigQ=>{/Preview=>false, /R=>131101}, /PubSec=>{/NonEFontNoWarn=>fal
se, /Date=>"2013-03-29 22:31:27 +0000", /R=>131101}, /App=>{/TrustedMode=>false,
/OS=>[/Win], /R=>458752, /Name=>/Exchange-Pro}}}
If i extract the keys (pdf.signature.keys) i get
/Type
/Contents
/Filter
/SubFilter
/ByteRange
/Location
/ContactInfo
/Reason
/M
/Prop_Build
Now, how do I reach the contents of these keys ?
I cannot simply do pdf.signature[/Location] , because ruby says it is a syntax error...
Any ideas?
I took a look at the source for origami-pdf, and it seems that the / prepending every key in that output is generated on-the-fly from Origami::Name.to_s. Also looking at its eql? definition it seems like it just compares it to the underlying string value. So this should work, have you tried it?
signature[Origami::Name.new('Location')]
As generating an Origami::Name object with /Location seems to be so hard, I solved this with a different approach :
location = pdf.signature[pdf.signature.keys[5]]
The Output returns Portugal, and this is the approach I will take, since the array's keys position are supposed to be static.
I would appreciate a more elegant solution though

Ruby LibXML - If a node exists, filter based on value

I am working on the following XML:
<digiprovMD ID="digiprov-3">
<mdWrap MDTYPE="PREMIS">
<xmlData>
<agent>
<agentIdentifier>
<agentIdentifierType>URI</agentIdentifierType
<agentIdentifierValue>info:fda/system-v0.16.2</agentIdentifierValue>
<agentIdentifierResult>outcome</agentIdentifierResult>
</agentIdentifier>
<agentName>DAITSS Account: UF</agentName>
<agentType>Affiliate</agentType>
</agent>
</xmlData>
</mdWrap>
</digiprovMD>
<digiprovMD ID="digiprov-4">
<mdWrap MDTYPE="PREMIS">
<xmlData>
<agent>
<agentIdentifier>
<agentIdentifierType>URI</agentIdentifierType>
<agentIdentifierValue>info:fda/system-v0.16.2</agentIdentifierValue>
</agentIdentifier>
<agentName>daitss system (v0.16.2)</agentName>
<agentType>software</agentType>
</agent>
</xmlData>
</mdWrap>
</digiprovMD>
<digiprovMD ID="digiprov-5">
<mdWrap MDTYPE="PREMIS">
<xmlData>
<agent>
<agentIdentifier>
<agentIdentifierType>URI</agentIdentifierType>
<agentIdentifierValue>info:fda/system-v0.16.2</agentIdentifierValue>
<agentIdentifierResult>source</agentIdentifierResult>
</agentIdentifier>
<agentIdentifier>
<agentIdentifierType>URI</agentIdentifierType>
<agentIdentifierValue>someotheruri</agentIdentifierValue>
<agentIdentifierResult>outcome</agentIdentifierResult>
</agentIdentifier>
<agentName>daitss system (v0.16.2)</agentName>
<agentType>software</agentType>
</agent>
</xmlData>
</mdWrap>
</digiprovMD>
I want to select all agents with a specific value of agentIdentifierValue say info:fda/system-v0.16.2, only if
1. it has no agentIdentifierResult tag associated with it and
2. if there is an agentIdentifierResult assocaited with it its value should be 'outcome'
So in this case both agents, digiprov-3 and digiprov-4 should be selected.
How do I write an xpath for this?
I tried this (pseudo-code):
(result = outcome and value = '#{uri.content}') or (value = '#{uri.content}')
but this selects the 3rd agent digiprov-5 too!
This should work:
'//digiprovMD[.//agentIdentifier[./agentIdentifierValue="info:fda/system-v0.16.2"][not(./agentIdentifierResult) or ./agentIdentifierResult = "outcome"]]'
Basically this is returning any digiprovMD nodes that include an agentIdentifier node with the specified agentIdentifierValue value, as well either no agentIdentifierResult or a agentIdentifierResult of "outcome".

Resources