urbit-aura 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (10) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +11 -0
  3. data/CHANGELOG.md +0 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +77 -0
  6. data/Rakefile +12 -0
  7. data/lib/aura.rb +334 -0
  8. data/lib/muk.rb +18 -0
  9. data/lib/ob.rb +118 -0
  10. metadata +68 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 993880e08fb2125ef19a39a73722871eee1f10fa8015c3c6a35d98a46d4e7b80
4
+ data.tar.gz: a87a2d689bd51dbe9537d14fbe7e0d4d3d5dfe6b4ba65e542077f0cb3631d387
5
+ SHA512:
6
+ metadata.gz: eef10f9a4babc15ff80141c8dc06bf3778c9cbccc07e81efe399db268cce0fb79b1e9af37b3be87d773f05f97535bd5638eb9281b869c208a75edb09439246a0
7
+ data.tar.gz: 1d8d895729563443c1875706f7a38ddcae0bf4332cadd0eb318ac8e7d0dc40cd8755059492d2b457edaad5c5c57e3312ecd4a8e1dd44c49ff2bf7714ff93980b
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ EnforcedStyle: double_quotes
9
+
10
+ Naming/MethodParameterName:
11
+ MinNameLength: 1
data/CHANGELOG.md ADDED
File without changes
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Matthew LeVan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # aura-rb
2
+
3
+ Parsing, conversion, and validation for Urbit date, phonetic name, and number
4
+ auras.
5
+
6
+ ## Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ $ bundle add urbit-aura
11
+
12
+ If bundler is not being used to manage dependencies, install the gem by
13
+ executing:
14
+
15
+ $ gem install urbit-aura
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ require 'aura'
21
+
22
+ Aura.version # => "0.1.0"
23
+
24
+ # @p
25
+ Aura::P.patp(0) # => "~zod"
26
+ Aura::P.patp("0") # => "~zod"
27
+ Aura::P.hex2patp("0x12345678") # => "~milbyt-wacmeg"
28
+ Aura::P.patp2hex("~zod") # => "00"
29
+ Aura::P.patp2dec("~zod") # => 0
30
+ Aura::P.clan("~zod") # => "galaxy"
31
+ Aura::P.clan("~mastyr-bottec") # => "planet"
32
+ Aura::P.sein("~mastyr-bottec") # => "~wanzod"
33
+ Aura::P.valid_pat?("~zod") # => true
34
+ Aura::P.valid_patp?("invalid") # => false
35
+ Aura::P.pre_sig("zod") # => "~zod"
36
+ Aura::P.de_sig("~zod") # => "zod"
37
+ Aura::P.cite("~mastyr-bottec") # => "~mastyr-bottec"
38
+
39
+ # @q
40
+ Aura::Q.patq(123456) # => "~doznec-fitrys"
41
+ Aura::Q.patq("123456") # => "~doznec-fitrys"
42
+ Aura::Q.hex2patq("1e240") # => "~doznec-fitrys"
43
+ Aura::Q.hex2patq("0x1e240") # => "~doznec-fitrys"
44
+ Aura::Q.patq2hex("~doznec-fitrys") # => "0001e240"
45
+ Aura::Q.patq2dec("~doznec-fitrys") # => 123456
46
+ Aura::Q.valid_patq?("~doznec-fitrys") # => true
47
+ Aura::Q.valid_patq?("invalid") # => false
48
+ ```
49
+
50
+ ## Development
51
+
52
+ TODO:
53
+
54
+ - [ ] Tests
55
+ - [ ] Dates (`@da`)
56
+ - [ ] More numbers (`@uv`, `@ud`, etc...)
57
+ - [ ] Linting errors (formally ignore rules, or fix)
58
+
59
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
60
+ `rake test` to run the tests. You can also run `bin/console` for an interactive
61
+ prompt that will allow you to experiment.
62
+
63
+ To install this gem onto your local machine, run `bundle exec rake install`. To
64
+ release a new version, update the version number in `version.rb`, and then run
65
+ `bundle exec rake release`, which will create a git tag for the version, push
66
+ git commits and the created tag, and push the `.gem` file to
67
+ [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at
72
+ https://github.com/urbit/aura-rb.
73
+
74
+ ## License
75
+
76
+ The gem is available as open source under the terms of the
77
+ [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
data/lib/aura.rb ADDED
@@ -0,0 +1,334 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative("ob")
4
+
5
+ # Functionality for wrangling Urbit `@da`, `@p`, `@q`, `@ux`, etc.
6
+ module Aura
7
+ VERSION = "0.1.0"
8
+
9
+ def self.version
10
+ VERSION
11
+ end
12
+
13
+ # List of all possible prefixes for @p encoding.
14
+ PREFIXES = %w[
15
+ doz mar bin wan sam lit sig hid fid lis sog dir wac sab wis sib
16
+ rig sol dop mod fog lid hop dar dor lor hod fol rin tog sil mir
17
+ hol pas lac rov liv dal sat lib tab han tic pid tor bol fos dot
18
+ los dil for pil ram tir win tad bic dif roc wid bis das mid lop
19
+ ril nar dap mol san loc nov sit nid tip sic rop wit nat pan min
20
+ rit pod mot tam tol sav pos nap nop som fin fon ban mor wor sip
21
+ ron nor bot wic soc wat dol mag pic dav bid bal tim tas mal lig
22
+ siv tag pad sal div dac tan sid fab tar mon ran nis wol mis pal
23
+ las dis map rab tob rol lat lon nod nav fig nom nib pag sop ral
24
+ bil had doc rid moc pac rav rip fal tod til tin hap mic fan pat
25
+ tac lab mog sim son pin lom ric tap fir has bos bat poc hac tid
26
+ hav sap lin dib hos dab bit bar rac par lod dos bor toc hil mac
27
+ tom dig fil fas mit hob har mig hin rad mas hal rag lag fad top
28
+ mop hab nil nos mil fop fam dat nol din hat nac ris fot rib hoc
29
+ nim lar fit wal rap sar nal mos lan don dan lad dov riv bac pol
30
+ lap tal pit nam bon ros ton fod pon sov noc sor lav mat mip fip
31
+ ].freeze
32
+
33
+ # List of all possible suffixes for @p encoding.
34
+ SUFFIXES = %w[
35
+ zod nec bud wes sev per sut let ful pen syt dur wep ser wyl sun
36
+ ryp syx dyr nup heb peg lup dep dys put lug hec ryt tyv syd nex
37
+ lun mep lut sep pes del sul ped tem led tul met wen byn hex feb
38
+ pyl dul het mev rut tyl wyd tep bes dex sef wyc bur der nep pur
39
+ rys reb den nut sub pet rul syn reg tyd sup sem wyn rec meg net
40
+ sec mul nym tev web sum mut nyx rex teb fus hep ben mus wyx sym
41
+ sel ruc dec wex syr wet dyl myn mes det bet bel tux tug myr pel
42
+ syp ter meb set dut deg tex sur fel tud nux rux ren wyt nub med
43
+ lyt dus neb rum tyn seg lyx pun res red fun rev ref mec ted rus
44
+ bex leb dux ryn num pyx ryg ryx fep tyr tus tyc leg nem fer mer
45
+ ten lus nus syl tec mex pub rym tuc fyl lep deb ber mug hut tun
46
+ byl sud pem dev lur def bus bep run mel pex dyt byt typ lev myl
47
+ wed duc fur fex nul luc len ner lex rup ned lec ryd lyd fen wel
48
+ nyd hus rel rud nes hes fet des ret dun ler nyr seb hul ryl lud
49
+ rem lys fyn wer ryc sug nys nyl lyn dyn dem lux fed sed bec mun
50
+ lyr tes mud nyt byr sen weg fyr mur tel rep teg pec nel nev fes
51
+ ].freeze
52
+
53
+ def bex(n)
54
+ 2**n
55
+ end
56
+
57
+ def rsh(a, b, c)
58
+ c / bex(bex(a) * b)
59
+ end
60
+
61
+ def met(a, b, c = 0)
62
+ b.zero? ? c : met(a, rsh(a, 1, b), c + 1)
63
+ end
64
+
65
+ def end_bits(a, b, c)
66
+ c % bex(bex(a) * b)
67
+ end
68
+
69
+ def patp2syls(name)
70
+ name.gsub(/[\^~-]/, "").scan(/.{1,3}/)
71
+ end
72
+
73
+ def valid_pat?(name)
74
+ raise ArgumentError, "valid_pat?: non-string input" unless name.is_a? String
75
+
76
+ leading_tilde = name.start_with?("~")
77
+
78
+ return false if !leading_tilde || name.length < 4
79
+
80
+ syls = patp2syls(name)
81
+ wrong_length = syls.length.odd? && syls.length != 1
82
+ syls_exist = syls.each_with_index.all? do |syl, index|
83
+ if index.odd? || syls.length == 1
84
+ SUFFIXES.include?(syl)
85
+ else
86
+ PREFIXES.include?(syl)
87
+ end
88
+ end
89
+
90
+ !wrong_length && syls_exist
91
+ end
92
+
93
+ # @p
94
+ module P
95
+ extend Aura
96
+
97
+ # Convert a hex-encoded string to a @p-encoded string.
98
+ def self.hex2patp(hex)
99
+ raise ArgumentError, "hex2patp: null input" if hex.nil?
100
+
101
+ patp(hex.delete_prefix("0x").to_i(16))
102
+ end
103
+
104
+ # Convert a @p-encoded string to a hex-encoded string.
105
+ def self.patp2hex(name)
106
+ raise ArgumentError, "patp2hex: not a valid @p" unless valid_pat?(name)
107
+
108
+ syls = patp2syls(name)
109
+ addr = syls.each_with_index.inject("") do |acc, (syl, idx)|
110
+ idx.odd? || syls.length == 1 ? acc + syl2bin(SUFFIXES.index(syl)) : acc + syl2bin(PREFIXES.index(syl))
111
+ end
112
+
113
+ bn = addr.to_i(2)
114
+ hex = Ob.fynd(bn).to_s(16)
115
+ hex.length.odd? ? hex.rjust(hex.length + 1, "0") : hex
116
+ end
117
+
118
+ # Convert a @p-encoded string to an integer.
119
+ def self.patp2dec(name)
120
+ patp2hex(name).to_i(16)
121
+ rescue ArgumentError
122
+ raise "patp2dec: not a valid @p"
123
+ end
124
+
125
+ # Find whether the given @p-encoded string is a galaxy, star, planet, moon,
126
+ # or comet.
127
+ def self.clan(who)
128
+ begin
129
+ name = patp2dec(who)
130
+ rescue ArgumentError
131
+ raise "clan: not a valid @p"
132
+ end
133
+
134
+ wid = met(3, name)
135
+ case wid
136
+ when (0..1) then "galaxy"
137
+ when 2 then "star"
138
+ when (3..4) then "planet"
139
+ when (5..8) then "moon"
140
+ else "comet"
141
+ end
142
+ end
143
+
144
+ # Find the parent of the given @p-encoded string.
145
+ def self.sein(name)
146
+ begin
147
+ who = patp2dec(name)
148
+ mir = clan(name)
149
+ rescue ArgumentError
150
+ raise "sein: not a valid @p"
151
+ end
152
+
153
+ res = case mir
154
+ when "galaxy" then who
155
+ when "star" then end_bits(3, 1, who)
156
+ when "planet" then end_bits(4, 1, who)
157
+ when "moon" then end_bits(5, 1, who)
158
+ else 0
159
+ end
160
+ patp(res)
161
+ end
162
+
163
+ # Validate a @p-encoded string.
164
+ def self.valid_patp?(str)
165
+ valid_pat?(str) && str == patp(patp2dec(str))
166
+ end
167
+
168
+ # Convert a number into a @p-encoded string.
169
+ def self.patp(arg)
170
+ raise ArgumentError, "patp: null input" if arg.nil?
171
+
172
+ n = arg.to_i # Assuming arg can be converted to an integer directly
173
+ sxz = Ob.fein(n)
174
+ dyy = met(4, sxz)
175
+
176
+ loop_fn = lambda do |tsxz, timp, trep|
177
+ log = end_bits(4, 1, tsxz)
178
+ pre = PREFIXES[rsh(3, 1, log)]
179
+ suf = SUFFIXES[end_bits(3, 1, log)]
180
+ etc = if (timp % 4).zero?
181
+ timp.zero? ? "" : "--"
182
+ else
183
+ "-"
184
+ end
185
+
186
+ res = pre + suf + etc + trep
187
+
188
+ timp == dyy ? trep : loop_fn.call(rsh(4, 1, tsxz), timp + 1, res)
189
+ end
190
+
191
+ dyx = met(3, sxz)
192
+
193
+ "~#{dyx <= 1 ? SUFFIXES[sxz] : loop_fn.call(sxz, 0, "")}"
194
+ end
195
+
196
+ def self.pre_sig(ship)
197
+ return "" if ship.nil? || ship.empty?
198
+
199
+ ship.strip.start_with?("~") ? ship.strip : "~#{ship.strip}"
200
+ end
201
+
202
+ def self.de_sig(ship)
203
+ return "" if ship.nil? || ship.empty?
204
+
205
+ ship.gsub("~", "")
206
+ end
207
+
208
+ def self.cite(ship)
209
+ return nil if ship.nil? || ship.empty?
210
+
211
+ patp = de_sig(ship)
212
+ case patp.length
213
+ when 56 # comet
214
+ pre_sig("#{patp[0..5]}_#{patp[50..55]}")
215
+ when 27 # moon
216
+ pre_sig("#{patp[14..19]}^#{patp[21..26]}")
217
+ else
218
+ pre_sig(patp)
219
+ end
220
+ end
221
+
222
+ def self.syl2bin(idx)
223
+ idx.to_s(2).rjust(8, "0")
224
+ end
225
+ end
226
+
227
+ # @q utility functions.
228
+ module Q
229
+ extend Aura
230
+
231
+ # Convert a number to a @q-encoded string.
232
+ def self.patq(arg)
233
+ n = arg.to_i
234
+ hex = n.to_s(16)
235
+ buf = hex.rjust((hex.length + 1) & ~1, "0").scan(/../).map(&:hex)
236
+ buf2patq(buf)
237
+ end
238
+
239
+ def self.buf2patq(buf)
240
+ # Split the buffer into chunks of 2, with a special case for odd-length buffers
241
+ chunked = if buf.length.odd? && buf.length > 1
242
+ [[buf[0]]] + buf[1..].each_slice(2).to_a
243
+ else
244
+ buf.each_slice(2).to_a
245
+ end
246
+
247
+ chunked.reduce("~") do |acc, elem|
248
+ acc + (acc == "~" ? "" : "-") + alg(elem, chunked)
249
+ end
250
+ end
251
+
252
+ # Convert a hex-encoded string to a @q-encoded string.
253
+ #
254
+ # Note that this preserves leading zero bytes.
255
+ def self.hex2patq(arg)
256
+ raise ArgumentError, "hex2patq: input must be a string" unless arg.is_a?(String)
257
+
258
+ arg = arg.delete_prefix("0x")
259
+ hex = arg.length.odd? ? arg.rjust(arg.length + 1, "0") : arg
260
+ buf = hex.to_s.scan(/../).map(&:hex)
261
+ buf2patq(buf)
262
+ end
263
+
264
+ # Convert a @q-encoded string to an integer.
265
+ def self.patq2dec(name)
266
+ patq2hex(name).to_i(16)
267
+ end
268
+
269
+ # Convert a @q-encoded string to a hex-encoded string.
270
+ #
271
+ # Note that this preservers leading zero bytes.
272
+ def self.patq2hex(name)
273
+ raise ArgumentError, "patq2hex: not a valid @q" unless valid_pat?(name)
274
+
275
+ chunks = name.delete_prefix("~").split("-")
276
+ dec2hex = ->(dec) { format("%02x", dec) }
277
+ splat = chunks.map do |chunk|
278
+ syls = chunk[0..2], chunk[3..]
279
+ if syls[1].nil? || syls[1].empty?
280
+ dec2hex.call(SUFFIXES.index(syls[0]))
281
+ else
282
+ dec2hex.call(PREFIXES.index(syls[0])) + dec2hex.call(SUFFIXES.index(syls[1]))
283
+ end
284
+ end
285
+
286
+ name.empty? ? "00" : splat.join("")
287
+ end
288
+
289
+ # Validate a @q-encoded string.
290
+ def self.valid_patq?(str)
291
+ valid_pat?(str) && eq_patq(str, patq(patq2dec(str)))
292
+ end
293
+
294
+ # Validate @q-encoded string equality.
295
+ def self.eq_patq(p, q)
296
+ # Convert p to hex, raise an exception if not valid
297
+ phex = begin
298
+ Aura::Q.patq2hex(p)
299
+ rescue ArgumentError
300
+ raise ArgumentError, "eq_patq: not a valid @q"
301
+ end
302
+
303
+ # Convert q to hex, raise an exception if not valid
304
+ qhex = begin
305
+ Aura::Q.patq2hex(q)
306
+ rescue ArgumentError
307
+ raise ArgumentError, "eq_patq: not a valid @q"
308
+ end
309
+
310
+ # Assuming eq_mod_leading_zero_bytes is defined elsewhere in your Ruby code
311
+ eq_mod_leading_zero_bytes(phex, qhex)
312
+ end
313
+
314
+ # Helper method to compare hex strings ignoring leading zero bytes
315
+ def self.eq_mod_leading_zero_bytes(hex1, hex2)
316
+ # Remove any leading zeros and compare
317
+ hex1.gsub(/^0+/, "") == hex2.gsub(/^0+/, "")
318
+ end
319
+
320
+ module_function
321
+
322
+ def prefix_name(byts)
323
+ byts[1].nil? ? PREFIXES[0] + SUFFIXES[byts[0]] : PREFIXES[byts[0]] + SUFFIXES[byts[1]]
324
+ end
325
+
326
+ def name(byts)
327
+ byts[1].nil? ? SUFFIXES[byts[0]] : PREFIXES[byts[0]] + SUFFIXES[byts[1]]
328
+ end
329
+
330
+ def alg(pair, chunked)
331
+ pair.length.odd? && chunked.length > 1 ? prefix_name(pair) : name(pair)
332
+ end
333
+ end
334
+ end
data/lib/muk.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("murmurhash3")
4
+
5
+ # ++ muk
6
+ module Muk
7
+ def self.muk(syd, key)
8
+ # Extract the least significant byte and the second byte
9
+ lo = key & 0xff
10
+ hi = (key >> 8) & 0xff
11
+
12
+ # Create a string from these two bytes
13
+ kee = [lo, hi].pack("CC")
14
+
15
+ # Use murmurhash3 gem to compute the hash
16
+ MurmurHash3::V32.str_hash(kee, syd)
17
+ end
18
+ end
data/lib/ob.rb ADDED
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative("muk")
4
+
5
+ # ++ ob
6
+ module Ob
7
+ # A pseudorandom function for j in (0..3)
8
+ def self.F(j, arg)
9
+ raku = [0xb76d5eed, 0xee281300, 0x85bcae01, 0x4b387af7]
10
+ Muk.muk(raku[j], arg)
11
+ end
12
+
13
+ def self.feis(arg)
14
+ Fe(4, 65_535, 65_536, 0xffffffff, method(:F), arg)
15
+ end
16
+
17
+ def self.Fe(r, a, b, k, f, m)
18
+ c = fe(r, a, b, f, m)
19
+ c < k ? c : fe(r, a, b, f, c)
20
+ end
21
+
22
+ def self.fe(r, a, b, f, m)
23
+ loop_fn = lambda do |j, ell, arr|
24
+ if j > r
25
+ if r.odd?
26
+ a * arr + ell
27
+ else
28
+ arr == a ? a * arr + ell : a * ell + arr
29
+ end
30
+ else
31
+ eff = f.call(j - 1, arr) # Assuming f is a Proc/lambda
32
+
33
+ tmp = if j.odd?
34
+ (ell + eff) % a
35
+ else
36
+ (ell + eff) % b
37
+ end
38
+
39
+ loop_fn.call(j + 1, arr, tmp)
40
+ end
41
+ end
42
+
43
+ left = m % a
44
+ right = m / a
45
+
46
+ loop_fn.call(1, left, right)
47
+ end
48
+
49
+ def self.tail(arg)
50
+ Fen(4, 65_535, 65_536, 0xffffffff, method(:F), arg)
51
+ end
52
+
53
+ def self.Fen(r, a, b, k, f, m)
54
+ c = fen(r, a, b, f, m)
55
+ c < k ? c : fen(r, a, b, f, c)
56
+ end
57
+
58
+ # TODO: FIXME
59
+ def self.fen(r, a, b, f, m)
60
+ # Inner recursive function using Ruby way of doing recursion
61
+ loop_fn = lambda do |j, ell, arr|
62
+ return a * arr + ell if j < 1
63
+
64
+ eff = f.call(j - 1, ell) # Assuming f is a Proc/lambda
65
+
66
+ # Same comment about deviation from B&R (2002)
67
+ tmp = if j.odd?
68
+ (arr + a - (eff % a)) % a
69
+ else
70
+ (arr + b - (eff % b)) % b
71
+ end
72
+
73
+ loop_fn.call(j - 1, tmp, ell)
74
+ end
75
+
76
+ ahh = r.odd? ? m / a : m % a
77
+ ale = r.odd? ? m % a : m / a
78
+
79
+ left = ale == a ? ahh : ale
80
+ right = ale == a ? ale : ahh
81
+
82
+ loop_fn.call(r, left, right)
83
+ end
84
+
85
+ def self.fein_loop(pyn)
86
+ lo = pyn & 0xffffffff
87
+ hi = pyn & 0xffffffff00000000
88
+
89
+ if (pyn >= 0x10000) && (pyn <= 0xffffffff)
90
+ 0x10000 + feis(pyn - 0x10000)
91
+ elsif (pyn >= 0x100000000) && (pyn <= 0xffffffffffffffff)
92
+ hi | fein_loop(lo)
93
+ else
94
+ pyn
95
+ end
96
+ end
97
+
98
+ def self.fein(arg)
99
+ fein_loop(arg)
100
+ end
101
+
102
+ def self.fynd_loop(cry)
103
+ lo = cry & 0xffffffff
104
+ hi = cry & 0xffffffff00000000
105
+
106
+ if (cry >= 0x10000) && (cry <= 0xffffffff)
107
+ 0x10000 + tail(cry - 0x10000)
108
+ elsif (cry >= 0x100000000) && (cry <= 0xffffffffffffffff)
109
+ hi | fynd_loop(lo)
110
+ else
111
+ cry
112
+ end
113
+ end
114
+
115
+ def self.fynd(arg)
116
+ fynd_loop(arg)
117
+ end
118
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: urbit-aura
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew LeVan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: murmurhash3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.7
27
+ description: Parsing, conversion, and validation for dates, phonetic names, and numbers.
28
+ email:
29
+ - matthew@coeli.network
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rubocop.yml"
35
+ - CHANGELOG.md
36
+ - LICENSE.txt
37
+ - README.md
38
+ - Rakefile
39
+ - lib/aura.rb
40
+ - lib/muk.rb
41
+ - lib/ob.rb
42
+ homepage: https://github.com/urbit/aura-rb
43
+ licenses:
44
+ - MIT
45
+ metadata:
46
+ homepage_uri: https://github.com/urbit/aura-rb
47
+ source_code_uri: https://github.com/urbit/aura-rb
48
+ changelog_uri: https://github.com/urbit/aura-rb/blob/master/CHANGELOG.md
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 3.0.0
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.5.16
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Urbit aura utilities.
68
+ test_files: []