├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── premake5.lua └── src └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # Build results 8 | [Dd]ebug/ 9 | [Dd]ebugPublic/ 10 | [Rr]elease/ 11 | [Rr]eleases/ 12 | x64/ 13 | x86/ 14 | bld/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | [Ll]og/ 18 | 19 | # Visual C++ cache files 20 | ipch/ 21 | *.aps 22 | *.ncb 23 | *.opendb 24 | *.opensdf 25 | *.sdf 26 | *.cachefile 27 | *.VC.db 28 | *.VC.VC.opendb 29 | 30 | # Visual Studio profiler 31 | *.psess 32 | *.vsp 33 | *.vspx 34 | *.sap 35 | 36 | # Visual Studio cache files 37 | # files ending in .cache can be ignored 38 | *.[Cc]ache 39 | # but keep track of directories ending in .cache 40 | !*.[Cc]ache/ 41 | 42 | # Backup & report files from converting an old project file 43 | # to a newer Visual Studio version. 44 | _UpgradeReport_Files/ 45 | Backup*/ 46 | UpgradeLog*.XML 47 | UpgradeLog*.htm 48 | 49 | # Premake generated project 50 | project/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "LuaInterface"] 2 | path = LuaInterface 3 | url = https://github.com/glua/LuaInterface 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Garry's Mod Lua 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gm_securerandom 2 | A module for generating secure random numbers and strings in Garry's Mod 3 | 4 | ## API 5 | 6 | #### random.Bytes(size) 7 | 8 | * size (number) - A whole number representing the amount of bytes you want returned 9 | 10 | Generates `size` bytes and returns them as a string. 11 | 12 | #### random.Number([min, max]) 13 | 14 | * min (number, optional, default 0) - The minimum value to generate 15 | * max (number, optional, default 1) - The maximum value to generate 16 | 17 | Generates a number between `min` and `max` and returns it. 18 | 19 | ## Usage 20 | 21 | #### Random bytes 22 | ```lua 23 | require("securerandom") 24 | print(util.Base64Encode(random.Bytes(16))) 25 | ``` 26 | 27 | #### Random number between 0 and 1 28 | ```lua 29 | require("securerandom") 30 | print(random.Number()) 31 | ``` 32 | 33 | #### Random number between 5 and 10.5 34 | ```lua 35 | require("securerandom") 36 | print(random.Number(5, 10.5)) 37 | ``` -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | solution "gm_securerandom" 2 | 3 | language "C++" 4 | location "project" 5 | flags { "StaticRuntime", "C++11" } 6 | targetdir "bin" 7 | includedirs { "LuaInterface/src/" } 8 | architecture "x86" 9 | 10 | configurations { "Release" } 11 | 12 | configuration "Release" 13 | optimize "On" 14 | 15 | project "gm_securerandom" 16 | defines { "GMMODULE" } 17 | files { 18 | "LuaInterface/src/GarrysMod/Lua/*.h", 19 | "src/*.h", 20 | "src/*.hpp", 21 | "src/*.hxx", 22 | "src/*.cpp", 23 | "src/*.cxx" 24 | } 25 | kind "SharedLib" 26 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "GarrysMod/Lua/Interface.h" 2 | #include 3 | #include 4 | #include 5 | 6 | std::random_device rd; 7 | std::mt19937 gen; 8 | 9 | int randomNumber(lua_State* state) { 10 | if (LUA->GetType(1) != GarrysMod::Lua::Type::NIL) { 11 | LUA->CheckType(1, GarrysMod::Lua::Type::NUMBER); 12 | LUA->CheckType(2, GarrysMod::Lua::Type::NUMBER); 13 | 14 | std::uniform_real_distribution dist(LUA->GetNumber(1), LUA->GetNumber(2)); 15 | LUA->PushNumber(dist(gen)); 16 | } else { 17 | std::uniform_real_distribution dist; 18 | LUA->PushNumber(dist(gen)); 19 | } 20 | 21 | return 1; 22 | } 23 | 24 | int randomBytes(lua_State* state) { 25 | LUA->CheckType(1, GarrysMod::Lua::Type::NUMBER); 26 | const double requestedSize = LUA->GetNumber(1); 27 | const size_t size = floor(LUA->GetNumber(1)); 28 | 29 | if (requestedSize < 0 || size != requestedSize) { 30 | LUA->ThrowError("size must be a whole number >= 0"); 31 | } 32 | 33 | std::uniform_int_distribution dist(SCHAR_MIN, SCHAR_MAX); 34 | std::vector bytes; 35 | bytes.resize(size); 36 | 37 | for (size_t i = 0; i < size; i++) { 38 | bytes[i] = (char)dist(rd); 39 | } 40 | 41 | LUA->PushString(bytes.data(), size); 42 | 43 | return 1; 44 | } 45 | 46 | GMOD_MODULE_OPEN() { 47 | gen.seed(rd()); 48 | gen.discard(700000); // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/lfsr04.pdf page 11 49 | 50 | LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); 51 | LUA->CreateTable(); 52 | LUA->PushCFunction(randomNumber); 53 | LUA->SetField(-2, "Number"); 54 | 55 | LUA->PushCFunction(randomBytes); 56 | LUA->SetField(-2, "Bytes"); 57 | LUA->SetField(-2, "random"); 58 | LUA->Pop(); 59 | return 0; 60 | } 61 | 62 | GMOD_MODULE_CLOSE() { 63 | return 0; 64 | } --------------------------------------------------------------------------------