Skip to content

Commit c700c32

Browse files
add cryptography functions (for mathieu's program)
1 parent 6e491d1 commit c700c32

4 files changed

Lines changed: 186 additions & 0 deletions

File tree

lib/code-ruby.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "bigdecimal/util"
77
require "date"
88
require "did_you_mean"
9+
require "digest"
910
require "json"
1011
require "language-ruby"
1112
require "mail"

lib/code/object/cryptography.rb

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# frozen_string_literal: true
2+
3+
class Code
4+
class Object
5+
class Cryptography < Object
6+
def self.call(**args)
7+
code_operator = args.fetch(:operator, nil).to_code
8+
code_arguments = args.fetch(:arguments, []).to_code
9+
arguments = code_arguments.raw
10+
11+
case code_operator.to_s
12+
when "md5"
13+
sig(args) { [Object, { format: String.maybe }] }
14+
code_md5(*arguments)
15+
when "sha1"
16+
sig(args) { [Object, { format: String.maybe }] }
17+
code_sha1(*arguments)
18+
when "sha256"
19+
sig(args) { [Object, { format: String.maybe }] }
20+
code_sha256(*arguments)
21+
when "sha384"
22+
sig(args) { [Object, { format: String.maybe }] }
23+
code_sha384(*arguments)
24+
when "sha512"
25+
sig(args) { [Object, { format: String.maybe }] }
26+
code_sha512(*arguments)
27+
else
28+
super
29+
end
30+
end
31+
32+
def self.code_md5(*arguments)
33+
payload = arguments[0]
34+
options = arguments[1] || Nothing.new
35+
code_payload = payload.to_code
36+
options = options.to_code
37+
options = Dictionary.new unless options.is_a?(Dictionary)
38+
code_format = options.code_get("format")
39+
code_format = String.new("hexdigest") if code_format.nothing?
40+
format = code_format.to_s.downcase
41+
42+
case format
43+
when "hexdigest", "hex"
44+
String.new(::Digest::MD5.hexdigest(code_payload.to_s))
45+
when "digest"
46+
String.new(::Digest::MD5.digest(code_payload.to_s))
47+
when "base64"
48+
String.new(
49+
::Base64.strict_encode64(::Digest::MD5.digest(code_payload.to_s))
50+
)
51+
else
52+
raise Error, "Cryptography: unknown format #{format.inspect}"
53+
end
54+
end
55+
56+
def self.code_sha1(*arguments)
57+
payload = arguments[0]
58+
options = arguments[1] || Nothing.new
59+
code_payload = payload.to_code
60+
options = options.to_code
61+
options = Dictionary.new unless options.is_a?(Dictionary)
62+
code_format = options.code_get("format")
63+
code_format = String.new("hexdigest") if code_format.nothing?
64+
format = code_format.to_s.downcase
65+
66+
case format
67+
when "hexdigest", "hex"
68+
String.new(::Digest::SHA1.hexdigest(code_payload.to_s))
69+
when "digest"
70+
String.new(::Digest::SHA1.digest(code_payload.to_s))
71+
when "base64"
72+
String.new(
73+
::Base64.strict_encode64(::Digest::SHA1.digest(code_payload.to_s))
74+
)
75+
else
76+
raise Error, "Cryptography: unknown format #{format.inspect}"
77+
end
78+
end
79+
80+
def self.code_sha256(*arguments)
81+
payload = arguments[0]
82+
options = arguments[1] || Nothing.new
83+
code_payload = payload.to_code
84+
options = options.to_code
85+
options = Dictionary.new unless options.is_a?(Dictionary)
86+
code_format = options.code_get("format")
87+
code_format = String.new("hexdigest") if code_format.nothing?
88+
format = code_format.to_s.downcase
89+
90+
case format
91+
when "hexdigest", "hex"
92+
String.new(::Digest::SHA256.hexdigest(code_payload.to_s))
93+
when "digest"
94+
String.new(::Digest::SHA256.digest(code_payload.to_s))
95+
when "base64"
96+
String.new(
97+
::Base64.strict_encode64(::Digest::SHA256.digest(code_payload.to_s))
98+
)
99+
else
100+
raise Error, "Cryptography: unknown format #{format.inspect}"
101+
end
102+
end
103+
104+
def self.code_sha384(*arguments)
105+
payload = arguments[0]
106+
options = arguments[1] || Nothing.new
107+
code_payload = payload.to_code
108+
options = options.to_code
109+
options = Dictionary.new unless options.is_a?(Dictionary)
110+
code_format = options.code_get("format")
111+
code_format = String.new("hexdigest") if code_format.nothing?
112+
format = code_format.to_s.downcase
113+
114+
case format
115+
when "hexdigest", "hex"
116+
String.new(::Digest::SHA384.hexdigest(code_payload.to_s))
117+
when "digest"
118+
String.new(::Digest::SHA384.digest(code_payload.to_s))
119+
when "base64"
120+
String.new(
121+
::Base64.strict_encode64(::Digest::SHA384.digest(code_payload.to_s))
122+
)
123+
else
124+
raise Error, "Cryptography: unknown format #{format.inspect}"
125+
end
126+
end
127+
128+
def self.code_sha512(*arguments)
129+
payload = arguments[0]
130+
options = arguments[1] || Nothing.new
131+
code_payload = payload.to_code
132+
options = options.to_code
133+
options = Dictionary.new unless options.is_a?(Dictionary)
134+
code_format = options.code_get("format")
135+
code_format = String.new("hexdigest") if code_format.nothing?
136+
format = code_format.to_s.downcase
137+
138+
case format
139+
when "hexdigest", "hex"
140+
String.new(::Digest::SHA512.hexdigest(code_payload.to_s))
141+
when "digest"
142+
String.new(::Digest::SHA512.digest(code_payload.to_s))
143+
when "base64"
144+
String.new(
145+
::Base64.strict_encode64(::Digest::SHA512.digest(code_payload.to_s))
146+
)
147+
else
148+
raise Error, "Cryptography: unknown format #{format.inspect}"
149+
end
150+
end
151+
end
152+
end
153+
end

lib/code/object/global.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ def call(**args)
148148
else
149149
Class.new(Base64)
150150
end
151+
when "Cryptography"
152+
sig(args) { Object.repeat }
153+
if code_arguments.any?
154+
Cryptography.new(*code_arguments.raw)
155+
else
156+
Class.new(Cryptography)
157+
end
151158
when "Json"
152159
sig(args) { Object.repeat }
153160
code_arguments.any? ? Json.new(*code_arguments.raw) : Class.new(Json)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
RSpec.describe Code::Object::Cryptography do
6+
it "returns sha256 hexdigest by default" do
7+
expect(Code.evaluate("Cryptography.sha256(:hello)").to_s).to eq(
8+
Digest::SHA256.hexdigest("hello")
9+
)
10+
end
11+
12+
it "supports base64 format for sha1" do
13+
expected = Base64.strict_encode64(Digest::SHA1.digest("hello"))
14+
15+
expect(
16+
Code.evaluate("Cryptography.sha1(:hello, format: :base64)").to_s
17+
).to eq(expected)
18+
end
19+
20+
it "raises on unknown formats" do
21+
expect do
22+
Code.evaluate("Cryptography.sha256(:hello, format: :unknown)")
23+
end.to raise_error(Code::Error, /unknown format/i)
24+
end
25+
end

0 commit comments

Comments
 (0)