├── README.md ├── Makefile └── csprng.js /README.md: -------------------------------------------------------------------------------- 1 | # csprng.xyz 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ZONEID=90f1f70c9d65eecd3bcae3a02b4de3e5 2 | ZONENAME=csprng.xyz 3 | 4 | deploy: 5 | cf worker upload-worker --script @csprng.js --zone-id $(ZONEID) 6 | 7 | call: 8 | curl https://$(ZONENAME)/v1/api 9 | -------------------------------------------------------------------------------- /csprng.js: -------------------------------------------------------------------------------- 1 | 2 | addEventListener('fetch', event => { 3 | event.respondWith(handleRequest(event.request)) 4 | }) 5 | 6 | 7 | let apiheaders = new Headers({'Access-Control-Allow-Origin': '*', 'Content-type': 'application/json'}) 8 | const index = ` 9 | 10 | 36 | 37 | 38 |

csprng

39 |

40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
/v1/apiRequest randomness from Cloudflare's edge servers.
Params:
lengthNumber of bytes. Valid for integer between 1 and 65535. Default 32
formatFormat of the returned randomness. Values: base64
49 |

Example

50 |
 51 | $ curl https://csprng.xyz/v1/api
 52 | {
 53 |         "Status": 200,
 54 |         "Data": "hp7RWuKfuUHWXvAQTUEtRits0chzZWHDjP58nVmwOZM=",
 55 |         "Time": "2018-10-14T07:03:39.250Z"
 56 | }
57 | See for yourself! 58 | 59 | `; 60 | 61 | // randombytes performs the generation of the random numbers. 62 | function randombytes(n) { 63 | var buf = new Uint8Array(n) 64 | crypto.getRandomValues(buf) 65 | var r = btoa(String.fromCharCode.apply(null, buf)) 66 | return buf 67 | } 68 | 69 | // respond generates the response object that is returned to clients in a 70 | // reusable way. If the status code isn't 200, the object that is returned 71 | // will say Message and not Data. This is so we don't re-use a field name 72 | // and put clients in to a position where they accidently use an error msg 73 | // as the randomness. 74 | function respond(statusCode, message) { 75 | var s = {}; 76 | if (statusCode != 200) { 77 | s['Message'] = message 78 | } else { 79 | s['Data'] = message 80 | } 81 | s['Time'] = new Date().toISOString(); 82 | s['Status'] = statusCode; 83 | return new Response(JSON.stringify(s), {status:statusCode, headers: apiheaders}) 84 | } 85 | 86 | // handlRandom is the /v1/api handler. 87 | function handleRandom(url) { 88 | var n = 32 89 | if (length = url.searchParams.get("length")) { 90 | if (length>65535 || length<1) { 91 | return respond(400, "Invalid byte length. n must be an integer between 0 and 65535.") 92 | } 93 | n = length 94 | } 95 | 96 | buf = randombytes(n) 97 | var format = "base64" 98 | if (fmt = url.searchParams.get("format")) { 99 | format = fmt ? fmt : format; 100 | } 101 | 102 | var r = "" 103 | switch (format) { 104 | case "base64": 105 | r = btoa(String.fromCharCode.apply(null, buf)) 106 | break; 107 | case "raw": 108 | r = ArrayBuffer.from(buf).toString('hex'); 109 | break 110 | default: 111 | return respond(400, "Invalid format. Allowed (base64, raw)") 112 | } 113 | return respond(200, r) 114 | } 115 | 116 | // handleRequest is the application router 117 | async function handleRequest(request) { 118 | var url = new URL(request.url) 119 | switch (url.pathname) { 120 | case "/v1/api": 121 | return handleRandom(url) 122 | default: 123 | return new Response(index, {headers: new Headers({'Content-type': 'text/html'})}); 124 | } 125 | } 126 | --------------------------------------------------------------------------------