Last active
March 13, 2019 11:35
-
-
Save rschiang/26d80b1e12cb8a09ea67f7fa95440954 to your computer and use it in GitHub Desktop.
SITCON 2019 Bingo Card proof-of-concept
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
crypto = require('crypto') | |
const sponsors = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', '+'] | |
const communities = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] | |
// 5x5 grid; 0: sponsor; 1: community | |
const patterns = [0b0010001010100010101000100, 0b1010001010000010101010000, | |
0b1000100100010100010010001, 0b0010010001010101000100100] | |
function md5Hash(token) { | |
var md5 = crypto.createHash('md5') | |
md5.update(token) | |
return md5.digest('hex') | |
} | |
function hex2Dec(s, i) { | |
var c = s.charCodeAt(i) | |
return c > 0x60 ? (c - 0x57) : (c - 0x30) | |
} | |
function swap(arr, a, b) { | |
var _ = arr[a] | |
arr[a] = arr[b] | |
arr[b] = _ | |
} | |
function generateBingo(token) { | |
var hash = md5Hash(token) | |
var shuffled_sponsors = [...sponsors] | |
for (i = 0; i < 16; i++) | |
swap(shuffled_sponsors, hex2Dec(hash, i), 15) | |
var shuffled_communities = [...communities] | |
for (i = 0; i < 8; i++) | |
swap(shuffled_communities, hex2Dec(hash, 16+i) % 8, 7) | |
// generate bingo card using predefined pattern | |
var grid = new Array(25) | |
var pattern = patterns[hex2Dec(hash, 24) % 4] | |
for (var i = 0; i < 25; i++) | |
if ((pattern >> i) & 1) | |
grid[i] = { 'type': 'community', 'name': shuffled_communities.shift() } | |
// free space in the middle | |
grid[12] = { 'type': 'free_space' } | |
// fill the remaining with sponsors | |
for (var i = 0; i < 25; i++) | |
if (!grid[i]) | |
grid[i] = { 'type': 'sponsor', 'name': shuffled_sponsors.shift() } | |
return grid | |
} | |
// Example code | |
// Usage: node bingo-pos.js [token] | |
var bingoGrid = generateBingo(process.argv[2] || '我能吞下玻璃而不傷身體') | |
console.log(bingoGrid) | |
var str = '='.repeat(21) + '\n' | |
for (var y = 0; y < 5; y++) { | |
for (var x = 0; x < 5; x++) { | |
var i = bingoGrid[y * 5 + x] | |
str += `| ${i.name || '@'}${i.type == 'community' ? '*' : ' '}` | |
} | |
str += '|\n' | |
} | |
str += '='.repeat(21) | |
console.log(str) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment