From 1863be5cb24cfe8158903344035d26cb7ae120c5 Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Tue, 22 Jan 2019 08:18:51 -0800 Subject: [PATCH 1/2] Unique GUID shim - Closes #153 --- lib/instances/HttpService.lua | 27 +++++++++++++++++++++++---- lib/instances/HttpService_spec.lua | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/instances/HttpService.lua b/lib/instances/HttpService.lua index 93e3004..a5ef19c 100644 --- a/lib/instances/HttpService.lua +++ b/lib/instances/HttpService.lua @@ -4,6 +4,15 @@ local json = import("../json") local HttpService = BaseInstance:extend("HttpService") +local guidCounter = 0 + +local GUID_DASH_POINTS = { + [8] = true, + [12] = true, + [16] = true, + [20] = true, +} + function HttpService.prototype:JSONEncode(input) return json.encode(input) end @@ -18,15 +27,25 @@ function HttpService.prototype:GenerateGUID(wrapInCurlyBraces) error(("Unable to cast %s to bool"):format(argType), 2) end + local zeroPadded = ("%032x"):format(guidCounter) + local guid = "" + for index = 1, 32 do + guid = guid .. zeroPadded:sub(index, index) + if GUID_DASH_POINTS[index] then + guid = guid .. "-" + end + end + guidCounter = guidCounter + 1 + --[[ `GenerateGUID` allows any value type for `wrapInCurlyBraces`, but it only omits the curly braces when `wrapInCurlyBraces` is set to `false` ]] - if wrapInCurlyBraces == false then - return "04AEBFEA-87FC-480F-A98B-E5E221007A90" - else - return "{04AEBFEA-87FC-480F-A98B-E5E221007A90}" + if wrapInCurlyBraces ~= false then + guid = "{" .. guid .. "}" end + + return guid end return HttpService \ No newline at end of file diff --git a/lib/instances/HttpService_spec.lua b/lib/instances/HttpService_spec.lua index ca45d3a..4c66d0f 100644 --- a/lib/instances/HttpService_spec.lua +++ b/lib/instances/HttpService_spec.lua @@ -20,6 +20,29 @@ describe("instances.HttpService", function() end) describe("GenerateGUID", function() + it("should have proper length guids", function() + local instance = HttpService:new() + local guid = instance:GenerateGUID(false) + + assert.equal(36, #guid) + end) + + it("should give unique guids", function() + local instance = HttpService:new() + local guids = {} + + for _ = 1, 100 do + guids[instance:GenerateGUID()] = true + end + + local guidsGenerated = 0 + for _ in pairs(guids) do + guidsGenerated = guidsGenerated + 1 + end + + assert.equal(100, guidsGenerated) + end) + it("should omit curly braces when wrapInCurlyBraces is false", function() local instance = HttpService:new() local guid = instance:GenerateGUID(false) From 4b2e90f8b49a6851e9b65da88038679008ef2352 Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Tue, 22 Jan 2019 11:59:53 -0800 Subject: [PATCH 2/2] Real GUIDs --- lib/instances/HttpService.lua | 63 ++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/lib/instances/HttpService.lua b/lib/instances/HttpService.lua index a5ef19c..8b5e660 100644 --- a/lib/instances/HttpService.lua +++ b/lib/instances/HttpService.lua @@ -4,14 +4,29 @@ local json = import("../json") local HttpService = BaseInstance:extend("HttpService") -local guidCounter = 0 +-- Credit to https://stackoverflow.com/a/32389020 +local AND, OR = 1, 4 -local GUID_DASH_POINTS = { - [8] = true, - [12] = true, - [16] = true, - [20] = true, -} +local function bit(a, b, oper) + local r, m, s = 0, 2^52 + repeat + s, a, b = a + b + m, a % m, b % m + r, m = r + m * oper % (s - a - b), m / 2 + until m < 1 + return r +end + +local function band(a, b) + return bit(a, b, AND) +end + +local function bor(a, b) + return bit(a, b, OR) +end + +local function tohex(number) + return ("%02x"):format(number) +end function HttpService.prototype:JSONEncode(input) return json.encode(input) @@ -27,15 +42,31 @@ function HttpService.prototype:GenerateGUID(wrapInCurlyBraces) error(("Unable to cast %s to bool"):format(argType), 2) end - local zeroPadded = ("%032x"):format(guidCounter) - local guid = "" - for index = 1, 32 do - guid = guid .. zeroPadded:sub(index, index) - if GUID_DASH_POINTS[index] then - guid = guid .. "-" - end - end - guidCounter = guidCounter + 1 + local random = math.random + + local guid = + ("%s%s%s%s-%s%s-%s%s-%s%s-%s%s%s%s%s%s"):format( + tohex(random(0, 255), 2), + tohex(random(0, 255)), + tohex(random(0, 255)), + tohex(random(0, 255)), + + tohex(random(0, 255)), + tohex(random(0, 255)), + + tohex(bor(band(random(0, 255), 0x0F), 0x40)), + tohex(random(0, 255)), + + tohex(bor(band(random(0, 255), 0x3F), 0x80)), + tohex(random(0, 255)), + + tohex(random(0, 255)), + tohex(random(0, 255)), + tohex(random(0, 255)), + tohex(random(0, 255)), + tohex(random(0, 255)), + tohex(random(0, 255)) + ) --[[ `GenerateGUID` allows any value type for `wrapInCurlyBraces`, but it