Last active
October 22, 2017 08:33
-
-
Save jb55/af967a43fb53185d17bb4b5087eca0bd to your computer and use it in GitHub Desktop.
This file contains 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
enum opcode_token | |
{ | |
// push value | |
_OP_0=1, | |
_OP_FALSE, | |
_OP_PUSHDATA1, | |
_OP_PUSHDATA2, | |
_OP_PUSHDATA4, | |
_OP_1NEGATE, | |
_OP_RESERVED, | |
_OP_1, | |
_OP_TRUE, | |
_OP_2, | |
_OP_3, | |
_OP_4, | |
_OP_5, | |
_OP_6, | |
_OP_7, | |
_OP_8, | |
_OP_9, | |
_OP_10, | |
_OP_11, | |
_OP_12, | |
_OP_13, | |
_OP_14, | |
_OP_15, | |
_OP_16, | |
// control | |
_OP_NOP, | |
_OP_VER, | |
_OP_IF, | |
_OP_NOTIF, | |
_OP_VERIF, | |
_OP_VERNOTIF, | |
_OP_ELSE, | |
_OP_ENDIF, | |
_OP_VERIFY, | |
_OP_RETURN, | |
// stack ops | |
_OP_TOALTSTACK, | |
_OP_FROMALTSTACK, | |
_OP_2DROP, | |
_OP_2DUP, | |
_OP_3DUP, | |
_OP_2OVER, | |
_OP_2ROT, | |
_OP_2SWAP, | |
_OP_IFDUP, | |
_OP_DEPTH, | |
_OP_DROP, | |
_OP_DUP, | |
_OP_NIP, | |
_OP_OVER, | |
_OP_PICK, | |
_OP_ROLL, | |
_OP_ROT, | |
_OP_SWAP, | |
_OP_TUCK, | |
// splice ops | |
_OP_CAT, | |
_OP_SUBSTR, | |
_OP_LEFT, | |
_OP_RIGHT, | |
_OP_SIZE, | |
// bit logic | |
_OP_INVERT, | |
_OP_AND, | |
_OP_OR, | |
_OP_XOR, | |
_OP_EQUAL, | |
_OP_EQUALVERIFY, | |
_OP_RESERVED1, | |
_OP_RESERVED2, | |
// numeric | |
_OP_1ADD, | |
_OP_1SUB, | |
_OP_2MUL, | |
_OP_2DIV, | |
_OP_NEGATE, | |
_OP_ABS, | |
_OP_NOT, | |
_OP_0NOTEQUAL, | |
_OP_ADD, | |
_OP_SUB, | |
_OP_MUL, | |
_OP_DIV, | |
_OP_MOD, | |
_OP_LSHIFT, | |
_OP_RSHIFT, | |
_OP_BOOLAND, | |
_OP_BOOLOR, | |
_OP_NUMEQUAL, | |
_OP_NUMEQUALVERIFY, | |
_OP_NUMNOTEQUAL, | |
_OP_LESSTHAN, | |
_OP_GREATERTHAN, | |
_OP_LESSTHANOREQUAL, | |
_OP_GREATERTHANOREQUAL, | |
_OP_MIN, | |
_OP_MAX, | |
_OP_WITHIN, | |
// crypto | |
_OP_RIPEMD160, | |
_OP_SHA1, | |
_OP_SHA256, | |
_OP_HASH160, | |
_OP_HASH256, | |
_OP_CODESEPARATOR, | |
_OP_CHECKSIG, | |
_OP_CHECKSIGVERIFY, | |
_OP_CHECKMULTISIG, | |
_OP_CHECKMULTISIGVERIFY, | |
// expansion | |
_OP_NOP1, | |
_OP_CHECKLOCKTIMEVERIFY, | |
_OP_NOP2, | |
_OP_CHECKSEQUENCEVERIFY, | |
_OP_NOP3, | |
_OP_NOP4, | |
_OP_NOP5, | |
_OP_NOP6, | |
_OP_NOP7, | |
_OP_NOP8, | |
_OP_NOP9, | |
_OP_NOP10, | |
// template matching params | |
_OP_SMALLINTEGER, | |
_OP_PUBKEYS, | |
_OP_PUBKEYHASH, | |
_OP_PUBKEY, | |
_OP_INVALIDOPCODE, | |
}; |
This file contains 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
#!/usr/bin/env python | |
# Easy Perfect Minimal Hashing | |
# By Steve Hanov. Released to the public domain. | |
# | |
# Based on: | |
# Edward A. Fox, Lenwood S. Heath, Qi Fan Chen and Amjad M. Daoud, | |
# "Practical minimal perfect hash functions for large databases", CACM, 35(1):105-121 | |
# also a good reference: | |
# Compress, Hash, and Displace algorithm by Djamal Belazzougui, | |
# Fabiano C. Botelho, and Martin Dietzfelbinger | |
import sys | |
DICTIONARY = sys.argv[1] | |
# Calculates a distinct hash function for a given string. Each value of the | |
# integer d results in a different hash value. | |
def hash( d, str ): | |
if d == 0: d = 0x01000193 | |
# Use the FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/ | |
for c in str: | |
d = ( (d * 0x01000193) ^ ord(c) ) & 0xffffffff; | |
return d | |
# Computes a minimal perfect hash table using the given python dictionary. It | |
# returns a tuple (G, V). G and V are both arrays. G contains the intermediate | |
# table of values needed to compute the index of the value in V. V contains the | |
# values of the dictionary. | |
def CreateMinimalPerfectHash( dict ): | |
size = len(dict) | |
# Step 1: Place all of the keys into buckets | |
buckets = [ [] for i in range(size) ] | |
G = [0] * size | |
values = [None] * size | |
for key in dict.keys(): | |
buckets[hash(0, key) % size].append( key ) | |
# Step 2: Sort the buckets and process the ones with the most items first. | |
buckets.sort( key=len, reverse=True ) | |
for b in xrange( size ): | |
bucket = buckets[b] | |
if len(bucket) <= 1: break | |
d = 1 | |
item = 0 | |
slots = [] | |
# Repeatedly try different values of d until we find a hash function | |
# that places all items in the bucket into free slots | |
while item < len(bucket): | |
slot = hash( d, bucket[item] ) % size | |
if values[slot] != None or slot in slots: | |
d += 1 | |
item = 0 | |
slots = [] | |
else: | |
slots.append( slot ) | |
item += 1 | |
G[hash(0, bucket[0]) % size] = d | |
for i in range(len(bucket)): | |
values[slots[i]] = dict[bucket[i]] | |
# Only buckets with 1 item remain. Process them more quickly by directly | |
# placing them into a free slot. Use a negative value of d to indicate | |
# this. | |
freelist = [] | |
for i in xrange(size): | |
if values[i] == None: freelist.append( i ) | |
for b in xrange( b, size ): | |
bucket = buckets[b] | |
if len(bucket) == 0: break | |
slot = freelist.pop() | |
# We subtract one to ensure it's negative even if the zeroeth slot was | |
# used. | |
G[hash(0, bucket[0]) % size] = -slot-1 | |
values[slot] = dict[bucket[0]] | |
return (G, values) | |
# Look up a value in the hash table, defined by G and V. | |
def PerfectHashLookup( G, V, key ): | |
d = G[hash(0,key) % len(G)] | |
if d < 0: return V[-d-1] | |
return V[hash(d, key) % len(V)] | |
dict = {} | |
line = 1 | |
keys = map(lambda x: x.strip(), open(DICTIONARY, "rt").readlines()) | |
for key in keys: | |
dict[key] = line | |
line += 1 | |
(G, V) = CreateMinimalPerfectHash( dict ) | |
Gstrs = ",".join(map(str, G)) | |
Vstrs = ",".join(map(str, V)) | |
header = open('oplookup.h', 'w') | |
header.write("#include \"misc.h\"\n") | |
header.write("extern int opcodes_g[{}];\n".format(len(G))) | |
header.write("extern int opcodes_v[{}];\n".format(len(V))) | |
header.close() | |
cfile = open('oplookup.c', 'w') | |
cfile.write("#include \"oplookup.h\"\n".format(Gstrs)) | |
cfile.write("int opcodes_g[{}] = {{ {} }};\n".format(len(G), Gstrs)) | |
cfile.write("int opcodes_v[{}] = {{ {} }};\n".format(len(V), Vstrs)) | |
cfile.close() |
This file contains 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
0 | |
FALSE | |
PUSHDATA1 | |
PUSHDATA2 | |
PUSHDATA4 | |
1NEGATE | |
RESERVED | |
1 | |
TRUE | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
NOP | |
VER | |
IF | |
NOTIF | |
VERIF | |
VERNOTIF | |
ELSE | |
ENDIF | |
VERIFY | |
RETURN | |
TOALTSTACK | |
FROMALTSTACK | |
2DROP | |
2DUP | |
3DUP | |
2OVER | |
2ROT | |
2SWAP | |
IFDUP | |
DEPTH | |
DROP | |
DUP | |
NIP | |
OVER | |
PICK | |
ROLL | |
ROT | |
SWAP | |
TUCK | |
CAT | |
SUBSTR | |
LEFT | |
RIGHT | |
SIZE | |
INVERT | |
AND | |
OR | |
XOR | |
EQUAL | |
EQUALVERIFY | |
RESERVED1 | |
RESERVED2 | |
1ADD | |
1SUB | |
2MUL | |
2DIV | |
NEGATE | |
ABS | |
NOT | |
0NOTEQUAL | |
ADD | |
SUB | |
MUL | |
DIV | |
MOD | |
LSHIFT | |
RSHIFT | |
BOOLAND | |
BOOLOR | |
NUMEQUAL | |
NUMEQUALVERIFY | |
NUMNOTEQUAL | |
LESSTHAN | |
GREATERTHAN | |
LESSTHANOREQUAL | |
GREATERTHANOREQUAL | |
MIN | |
MAX | |
WITHIN | |
RIPEMD160 | |
SHA1 | |
SHA256 | |
HASH160 | |
HASH256 | |
CODESEPARATOR | |
CHECKSIG | |
CHECKSIGVERIFY | |
CHECKMULTISIG | |
CHECKMULTISIGVERIFY | |
NOP1 | |
CHECKLOCKTIMEVERIFY | |
NOP2 | |
CHECKSEQUENCEVERIFY | |
NOP3 | |
NOP4 | |
NOP5 | |
NOP6 | |
NOP7 | |
NOP8 | |
NOP9 | |
NOP10 | |
SMALLINTEGER | |
PUBKEYS | |
PUBKEYHASH | |
PUBKEY | |
INVALIDOPCODE |
This file contains 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
#include "oplookup.h" | |
int opcodes_g[120] = { 1,-118,0,2,-116,0,0,2,0,0,0,-114,3,-111,8,0,0,0,0,8,-110,-107,1,0,0,-101,0,-98,0,-92,0,10,1,1,0,0,0,0,-89,0,5,-88,2,-87,4,-86,-79,-78,2,0,-74,-73,-72,-70,-69,0,1,1,-63,-61,-59,-56,-55,0,0,0,-53,0,-49,0,1,-48,0,-47,0,0,2,-46,1,0,5,3,-44,-41,0,2,-38,-33,-30,14,-29,0,2,0,-28,0,-27,0,0,-26,0,0,-23,0,0,0,-20,1,-18,0,-15,-12,8,1,0,-10,10,2,6,7 }; | |
int opcodes_v[120] = { 66,111,5,90,50,33,76,105,6,104,65,77,55,32,116,49,71,85,75,113,60,26,52,88,46,57,86,41,96,36,18,19,69,56,95,63,42,51,30,117,4,13,80,64,68,72,67,59,74,89,83,34,44,53,24,23,48,39,22,47,21,70,20,109,112,7,103,40,25,43,8,2,9,73,99,110,81,14,15,106,97,45,17,16,29,12,10,1,120,114,58,118,31,82,37,62,92,102,3,108,107,11,28,93,27,94,79,115,98,78,87,54,38,101,35,100,119,91,84,61 }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment