<commit_before>// vim: tabstop=2 shiftwidth=2

package main

import (
	"crypto/rand"
	"math/big"
	"strings"
)

// popstr takes a pointer to a string slice and pops the last element
func popstr(s *[]string) (element string) {
	slice := *s
	element, slice = slice[len(slice) - 1], slice[:len(slice) - 1]
	*s = slice
	return
}

// insstr inserts a string (text) into a slice at position pos
func insstr(s *[]string, text string, pos int) (length int) {
	slice := *s
	slice = append(slice, "foo")
	copy(slice[pos + 1:], slice[pos:])
	slice[pos] = text
	*s = slice
	length = len(slice)
	return
}

// randint returns a cryptographically random number in range 0-max
func randint(max int) (rint int) {
	r, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
	if err != nil {
		panic(err)
	}
	rint = int(r.Uint64())
	return
}

// str_contains tests for the membership of a string in a slice
func str_contains(s string, slice []string) bool {
	for _, n := range slice {
		if n == s {
			return true
		}
	}
	return false
}

// candidates returns a slice of remailer addresses suitable for a given hop
func candidates(p map[string]pubinfo, dist []string, exit bool) (c []string) {
	c = make([]string, 0, len(p))
  // Create a slice of addresses (for random node selection)
  for addy := range p {
		if exit && strings.Contains(p[addy].caps, "M") {
			// Exits are required and this is a Middle
			continue
		}
		if str_contains(addy, dist) {
			// Excluded due to distance
			continue
		}
		c = append(c, addy)
	}
	return
}

// chain_build takes a chain string and constructs a valid remailer chain
func chain_build(chainstr string, pub map[string]pubinfo, xref map[string]string) (out_chain []string) {
	dist := 3 // TODO Needs to be user-defined
	if dist > max_chain_length {
		dist = max_chain_length
	}
	var exist bool // Test for key existence
	var addresses []string // Candidate remailers for each hop
	in_chain := strings.Split(chainstr, ",")
	if len(in_chain) > max_chain_length {
		panic("Too many hops in chain")
	}
	// If dist is greater than the actual chain length, all hops will be unique.
	if dist > len(in_chain) {
		dist = len(in_chain)
	}
	var distance []string
	in_dist := make([]string,0, dist) // n distance elements of input chain
	out_dist := make([]string,0, dist) // n distance elements of output chain
	out_chain = make([]string, 0, len(in_chain))
	// This iteration of in_chain converts any shortnames to addresses
	for n, hop := range in_chain {
		if strings.Contains(in_chain[n], "@") {
			// Selection via remailer email address
			_, exist = pub[hop]
	    if ! exist {
				panic(hop + ": Remailer address not known")
			}
		} else if in_chain[n] != "*" {
			// Selection via remailer shortname
			_, exist = xref[hop]
			if ! exist {
				panic(hop + ": Remailer name not known")<commit_msg>Replace a couple of panics with graceful exits.<commit_after>// vim: tabstop=2 shiftwidth=2

package main

import (
	"crypto/rand"
	"math/big"
	"strings"
	"os"
	"fmt"
)

// popstr takes a pointer to a string slice and pops the last element
func popstr(s *[]string) (element string) {
	slice := *s
	element, slice = slice[len(slice) - 1], slice[:len(slice) - 1]
	*s = slice
	return
}

// insstr inserts a string (text) into a slice at position pos
func insstr(s *[]string, text string, pos int) (length int) {
	slice := *s
	slice = append(slice, "foo")
	copy(slice[pos + 1:], slice[pos:])
	slice[pos] = text
	*s = slice
	length = len(slice)
	return
}

// randint returns a cryptographically random number in range 0-max
func randint(max int) (rint int) {
	r, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
	if err != nil {
		panic(err)
	}
	rint = int(r.Uint64())
	return
}

// str_contains tests for the membership of a string in a slice
func str_contains(s string, slice []string) bool {
	for _, n := range slice {
		if n == s {
			return true
		}
	}
	return false
}

// candidates returns a slice of remailer addresses suitable for a given hop
func candidates(p map[string]pubinfo, dist []string, exit bool) (c []string) {
	c = make([]string, 0, len(p))
  // Create a slice of addresses (for random node selection)
  for addy := range p {
		if exit && strings.Contains(p[addy].caps, "M") {
			// Exits are required and this is a Middle
			continue
		}
		if str_contains(addy, dist) {
			// Excluded due to distance
			continue
		}
		c = append(c, addy)
	}
	return
}

// chain_build takes a chain string and constructs a valid remailer chain
func chain_build(chainstr string, pub map[string]pubinfo, xref map[string]string) (out_chain []string) {
	dist := 3 // TODO Needs to be user-defined
	if dist > max_chain_length {
		dist = max_chain_length
	}
	var exist bool // Test for key existence
	var addresses []string // Candidate remailers for each hop
	in_chain := strings.Split(chainstr, ",")
	if len(in_chain) > max_chain_length {
		panic("Too many hops in chain")
	}
	// If dist is greater than the actual chain length, all hops will be unique.
	if dist > len(in_chain) {
		dist = len(in_chain)
	}
	var distance []string
	in_dist := make([]string,0, dist) // n distance elements of input chain
	out_dist := make([]string,0, dist) // n distance elements of output chain
	out_chain = make([]string, 0, len(in_chain))
	// This iteration of in_chain converts any shortnames to addresses
	for n, hop := range in_chain {
		if strings.Contains(in_chain[n], "@") {
			// Selection via remailer email address
			_, exist = pub[hop]
	    if ! exist {
				fmt.Fprintf(os.Stderr, "%s: Remailer address not known\n", hop)
				os.Exit(1)
			}
		} else if in_chain[n] != "*" {
			// Selection via remailer shortname
			_, exist = xref[hop]
			if ! exist {
				fmt.Fprintf(os.Stderr, "%s: Remailer shortname not known\n", hop)
				os.Exit(1)
{'fraction_non_alphanumeric': 0.12408632091890011, 'fraction_numerical': 0.005569091541942221, 'mean_word_length': 3.543083003952569, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6210471', 'n_tokens_mistral': 2060, 'n_tokens_neox': 1937, 'n_words': 688}