list of entries

[all entries]

"free" as in "actually free"

some of my favorite sites

quantification of bitstring randomess

specialized POST account retrieval system

the parse interpreted algorithm language

recent updates

telnet server with sockets and multithreading

working with brainfuck


"free" as in "actually free"

not as in "free software"


There is a great, unknown enemy of the free software movements of this technological age. It is not Microsoft; it is not even the U.S. government; it is the attempted free license, the ironically restrictive license which is championed by some to grant freedom but which in fact hinders it.

There are several examples of this which I have found, the most horrible being the copyleft and its derivatives. Instead of a complete rejection of the ideas and purposes of copyright, copyleft creates its own restrictions that deprive the user of absolute freedom.

Copyleft unironically and earnestly claims, in a facade of freedom, that the material is not restricted, that anyone may use it in any way, distributing it, modifying it, blah blah, but that this license not be removed from the software or any modified or extended versions.

The intention of copyleft is clear: that these monstrously evil companies that we have come to know and hate, CEO's maniacally laughing at every uninformed purchase of Excel or Photoshop, not have the right to use this free software in their corporate products, which would supposedly go against the popularization and adoption of free alternatives in their benefit. Not only do they not give a damn about this insignificant piece of text, as their software can never be screened for compliance with RMS's sort-of-libertarian dreamwork (however, the impotence of this nonsense is not at all the focus or even a supportive point of my argument), but in actuality the effort to promote the production and adoption of free software is pretty simple: to produce it and to allow its use in every way absolutely, without restriction. Yes, I know it is unimaginable to not restrict something.

So-called "permissive" licenses, like ISC, MIT/X11, zlib, et cetera get the bullet too, although infinitesimally so, as they (usually) do not place copyleft restrictions on software derivatives.

Licenses like this invoke the power of the state just as copyright does, preventing absolutely free use of the material for any purpose. This does not reject the state and corporate power-by-extention-of-the-state, but indeed it utilizes it just as importantly, (attemptedly) ensuring that there are legal grounds to punish perpetrators for misuse of the material.

Fortunately, there are people who get it. Rob Landley, the author of the Zero-Clause BSD license (formerly Free Public License 1.0.0) created the perfect license. It does exactly what is necessary in a governmental system where someone can find grounds to sue a producer for just about any reason: it states erasure of liability for the producer. Unlicense does this and a little more. Arto Bendiken excellently articulates the underlying philosophy of the Unlicense: it does what the 0BSD does, with the added declaration of dedication of the material to the public domain. This is something which should be implied but which "some backward jurisdiction," as he puts it, might not see.

Without making this post an all-encompassing rambling about the various esoteric licenses, here are some comments on a few that I have seen. The WTFPL comes close to being free, but I would have excluded the name-change clause just for the sake of absolutism. I will probably never be buena onda, but this one is kind of cute. Finally, the maximal CC0 sucks (as any license that takes two years to write does). I am fairly certain that there are plenty more fun licenses that I have not mentioned which would evoke plenty of indignant huffs from Stallman and chuckles from people with a sense of humor, but I have not looked into them.

But how can authors possibly gain recognition without their names splattered all over the source code? How can one ever make the claim that a new feature of Windows started as free software? In order to prevent someone from distributing their software under your software's name or distributing your software under a different name, in essence, to prevent undue credit, let's take a different approach. It is my belief that, instead of using a restrictive license, is the responsibility of the original author to publish indisputable proof of their authorship in order to take credit and dispel false blame for unforeseen mishaps (e.g. erroneous use of the software and a subsequent lawsuit).

So far, I have not come across a simple solution to this problem that is accessible and (inb4 Wayback Machine) not centralized. An authorship system could be designed using blockchain or a similar technology such that an individual can publish material which is undeniably linked to a particular time and identity (i.e. through a key pair) through a decentralized system. Maksym Trilenko and several researchers have already proposed this idea. However, as far as I have looked, there does not seem to be a popular or even usable implementation of this yet. This should be soon-to-come.

The conversation about this concept is altogether very quiet. The importance of authorship from an individualist standpoint is powerful, and not enough recognition is given to recognition. People can make money from their proprietary software, but just give me a place in history.

Free software should actually be free. Make the right choice when publishing open-source material, and place it in the public domain, with or without a license. If getting those ones and zeroes far and wide is your objective, then give them that much more space to roam. Unencumber your software.

some of my favorite sites

Here is a list of websites and online resouces that I often use or visit, and which I would like to uphold.


Internet Archive::Wayback Machine


I use this website all of the time; in fact, I use it to link to an archived page of the multiVAX website:


This site is most likely my favorite. This extensive archive of even the most obscure resources has provided me with finding many pages and websites that are no longer active.



I use Google as my primary search engine. It is immensely helpful for searching given their strict search operators, like intext: and site:.

Their image search tools are also very helpful.



This free encyclopedia is another website of utmost importance for me. When it comes to learning about various topics, Wikipedia is truly indespensible.



This list would truly be incomplete if I were to exclude Zamzar. This service, which performs multimedia conversion between many file formats, has been an extremely beneficial tool.

I have used this for various other conversions which I could not complete with GIMP, VLC, or another software.



This website has been very valuable to me, by allowing me to create beautiful, high-resolution formulas, which I have used on this website and often in my academic work.

ChemDoodle::2D Sketcher


In a similar vein to latex2png, I use ChemDoodle's 2D Sketcher for much of my academic work. It is a great tool for creating 2-dimensional chemical structures online.



Enter a paper DOI, and never get stuck at a publisher paywall again.

At the time of writing, sci-hub.tw is the active domain name.

VPN Gate


I use the .ovpn files offered on the site in conjunction with Tunnelblick, an open-source VPN software, in order to quickly connect to a VPN.

It is very easy to connect to a VPN, and the academic basis for this hub creates a minimal VPN solution without the flashy, ad-filled experience of a typical VPN consumer product.

IETF Tools::Requests for Comments


I use this very often for consulting RFC documentation. A particular favorite of mine is RFC 1149.



This is the best online calculator I have found.

quantification of bitstring randomness

In this post, I propose an uncomplicated and superficial method by which to quantify bitstring randomness based on comprised repetition.


The maximum number of transitions from 0 to 1 or from 1 to 0 within a bitstring of a given length, n that can exist, n minus 1. There is also an ideal number of transitions, which is the maximum divided by 2. his would be expressed as follows:

T_max = n - 1, T_ideal=T_max / 2

A bitstring with exactly Tmax transitions would be an alternating 0-1-0-[..] or 1-0-1-[..] bitstring, with an absolutely predictable order. A bitstring with zero transitions, i.e. 0-0-0-[..] or 1-1-1-[..], will also have absolute predictability.

Bitstrings with exactly Tideal transitions will be the most unpredictable, because each pair of bits has exactly the same probability of containing a transition or not.

In order to create an expression that will return the randomness of a bitstring, by these terms, the ratio of the actual number of transitions to the ideal will be taken into account.

This ratio will have a certain distance from 1, showing how far from ideal it is. This is squared in order to accentuate predictability at larger distances from 1 and for symmetry about 1. This value is subtracted from 2, and the base-2 logarithmic value of this is taken in order to generate an output value that will be closer to 0 when the input approaches 1 and an output of 1 when the input approaches 2, where the higher value shows a higher randomness. The full expression is as follows:

R = log_2(2 - (1 - T / T_ideal) ^ 2)

In order to grasp what shape this expression produces for proportion of transitions in a sufficiently large bitstring, the following function is constructed:

f(x) = log_2(2 - (1 - x / T_ideal) ^ 2), {x in Z : x in [0, T_max]}

When this function is plotted over the range of possible transitions for a given bitstring, the following curve arises, with values of 0 given for bitstrings with the least ideal proportions of transitions and a value of 1 given for the ideal proportion of transitions, 0.5:


However, in merely using this expression, it can be found that clearly predictable bitstrings can be easily constructed which would be shown to have very low predictability, based on the score given, for example:


This bitstring would be given the score of 0.99, a very high score for a bitstring with perfect predictability. The fact that almost a perfect number of transitions exist in this bitstring causes it to be judged as highly unpredictable, although these transitions are placed very predictably from each other.

In order to create a program that would judge this, justly, as the predictable bitstring that it is, another approach must be taken. I have proposed a way to evaluate bitstrings such that all ways of organizing it consistently will be examined, and the lowest score achieved will be assigned to this bitstring as a more correct score.

The bitstrings are broken up into segments of variable length, and each bit is taken and placed into a new bitstring in the order that they appear in the given segments. All segment lengths ranging from 1 to the length of the bitstring are tested. However, it is unnecessary to test beyond segment lengths of the length of the bitstring divided by 2, because these rearrangements are the bitstring itself. For example, the bitstring above would be tested in segments of all lengths ranging from 1 to 8.

This bitstring will be separated into segments of a given length (e.g. 2). The first bit of each segment will be taken, and then the second bit of each segment will be taken. The resulting concatenated bitstring is evaluated. Following the 2-length example, the process is outlined in the following image:

bitstring rearrangement diagram

In this example, the bitstring is evaluated to the score of 0.00, because there are a maximum number of transitions possible in this consistent arrangement.

Similarly, using this same type of evaluation on a longer bitstring, the binary representation of the ASCII string This is an encoded ASCII string.:


If evaluated without rearrangement, this bitstring would be given a score of 0.99. However, the consistency in ASCII character binary representations allows for a less random bitstring to be created when bits are taken in order from segments of length 8:


Because of the lower randomness of this bitstring, a lower score of 0.92 is given. The lowest score generated from the computation of randomness scores for rearrangements of any possible length—also known as the rearrangement parameter—is assigned to the bitstring.

If we define a bitstring as an n-tuple, for example:

bitstring = (0 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0)

A set of all indices within this n-tuple—also the set rearrangement parameters—is defined:

S = {i in Z : 1 <= i <= n}

Then the bistring can be rearranged using the process described above using a mathematical formula. The actual rearrangement of the bistring, given needlessly in the form of a piecewise function—please bear with me—is as follows:

I found a hack that allows the index formula in the first piece to be somewhat simplified (note the change in conditionals):

In order to calculate the number of transitions in each rearrangement, the following function is used:

Here, I have used a sumation of the negated equality comparison of each pair within the bistring to give the number of transitions within the bitstring. A randomness score is then taken for each rearrangement, and the minimum value generated from rearrangement for any i in S, is calculated:

The future applications of this development are currently unclear, but I contend that the scores these bitstrings are given by this program are correlated to the compressibility of the bitstring, where lower scores correlate to higher compressibility.

I am sure that a program could be constructed which would more accurately represent the randomness of a given bitstring. However, I have not yet found a more holistic method. This is something I hope to investigate further.

I have created a much faster C implementation of this program for those who find this useful. It performs exactly the same function but much more quickly, and it is more portable.

specialized POST account retrieval system

Since this entry was composed, Zero Hedge has implemented HTTPS on their website, which has currently disabled this program from functioning properly.


Because of the stigma that surrounds users who have recently joined Internet forums, it can often be easy to develop a high esteem within a given forum by merely using an older account.

In the case of Zero Hedge, a financial news website, many users created their accounts many years ago, and this is visible on the account pages for these users. It has been found that a program could be devised which creates a list of users based on their account chronology and attempts to gain access using a list of unsecure passwords.

I have developed an account retrieval system which exploits security vulnerabilities on the Zero Hedge website in order to garner login credentials for accounts that use unsecure passwords.

In observing Zero Hedge user account pages, it was found that the accounts are given specific identification numbers when they are created. When this number is appended to http://zerohedge.com/user/, a redirection to the page of that user account will occur.

For example, http://zerohedge.com/user/5 redirects to http://zerohedge.com/users/tyler-durden, which returns the following information in the head of the page:

<link rel="canonical" href="http://www.zerohedge.com/users/tyler-durden" />
<meta property="og:url" content="http://www.zerohedge.com/users/tyler-durden" />

The following was written in order to automate username collection, in which number is incremented to try each account in order of their creation:

response = requests.get("http://zerohedge.com/user/" + number).text

if "Page Not Found" not in response:
	entry.append(response[response.index("canonical") + 48:response.index("og:url") - 21])

	entry.append(response[response.index("<title>") + 7:response.index(" | Zero Hedge")])

By finding where in the response the username and title are located, these substrings can be appended to the user entry within the program.

In the user account pages, the username is consistently found forty-eight positions after canonical to twenty-one positions before og:url.

The display title is consistently found seven positions after <title> to the position immediately before | Zero Hedge.

However, attaining the usernames is the easier part of the effort. In order to gain the password for a given account, more effort must be made, and a directly more sophisticated program must be written to effectuate the necessary procedure.

Observing again the source of the website, this time specifically of the login page, the form for login POST submission, http://zerohedge.com/user/, was found. Similarly to the program used to find the usernames based on the page returned after the URL was requested, this program will merely parse the returned information after a POST request is made using each set of credentials attempted.

For each username found, each password contained in a specified list is attempted. If the page returns a certain string in its source, it can be determined whether the login attempt was successful, for example:

for item in [entry[1], entry[2]] + passwords:
	data = {"form_id": "user_login", "name": entry[1], "pass": item}

	response = requests.post("http://zerohedge.com/user/", data).text

After the request is made, the response that is received is examined to determine whether the login attempt was successful:

if "/user/password" not in response:
	output(entry + [item])

In this section, response denotes the source returned after the login POST request is made, entry denotes the known information—the username and display title of the user, and item denotes the password being attempted. output() denotes a tabulated output function.

As the program runs, the output generated will give the user credentials determined from the public user account page as well as the password that resulted in a successful login attempt, for example, if a list of user accounts is attempted, and if qwerty was the password for each of them:

Number  Username                        Title                           Password
0       example-user-1                  Example User 1                  qwerty
1       example-user-2                  Example User 2                  qwerty
2       example-user-3                  Example User 3                  qwerty
3       example-user-4                  Example User 4                  qwerty

The login form has no form of protection against robots. This allows for retrieval of accounts in immediate succession and without the necessity for performing a human action, like CAPTCHA.

Not every account will have a password found in a given password list, but many accounts will use unsecure passwords. This program will only try as many passwords as are contained in the password list in addition to the username itself and the display title as passwords. Usernames for which the password is not found will not be shown in the output.

Although the Zero Hedge front-end is wanting in some form of protection against robots, their back-end does have protection against denial-of-service attacks. To combat this, the program includes a mere pass statement when it encounters a request limit error, giving enough time for the server to begin accepting new requests.

This has the unintended side effect of skipping that particular user and password combination, making the account retrieval imperfect. A function for repeating skipped combinations has yet to be implemented.

I have incorporated multithreading in order to allow this program to send multiple requests at once, which has shown, in practice, to make it garner account credentials more quickly.

Other websites like this may have similar vulnerabilities, and the same concept represented in this project could be used in a program specialized for another website. This project helps illustrate the ease of garnering account credentials using an unornamented program.

the parse interpreted algorithm language

This project concerns the production of the parse language and its interpreter.


The objective of this project is to create an unornamented algorithm language which has extensive applications in the processing of bitstring inputs. As an important disclaimer, this language is still very much in development, and it is becoming more sophisticated. The language is foreseen to eventually support recursive functions and conditionals, but currently, the language is relatively limited in function.

An algorithm expression will be made which specifies the operations to be evaluated using the bits from specified positions in the bitstring. The interpreter works with the input in segments of the number of characters of the number of variables specified in the expression.

For example, if the bitstring, 00011011, is evaluated with the expression, (0|1)&~(0&1), this will evaluate as follows, in which arrows express levels of evaluation:

(0|1)&~(0&1)->{0,1} (alternatively represented as (a|b)&~(a&b)->{a,b})
    ->00,01,10,11 each evaluated with the expression

This gives the output of 0110.

Expressions comprised of comma-delimited phrases allow for multiple operations to be performed on the same inputs, for example:


This expression, when used to evaluate the same bitstring input used in the previous example, will evaluate as follows:

(0|1),~(0&1)->{0,1} (alternatively represented as (a|b),~(a&b)->{a,b})
    ->00,01,10,11 each evaluated with the expression

This gives the output of 01111110.

If this output were to be evaulated with the expression 0&1, the functional difference between the two preceding expressions, the bitstring would be evaluated as follows:

0&1->{0,1} (alternatively represented as a&b->{a,b})
    ->01,11,11,10 each evaluated with the expression

This gives the output of 0110, similarly to the first expression, because it takes the input in 2-groups and does an and operation on them, which is the functional difference between the previous two expressions.

This algorithm language can be used for many more applications than simply operating with 2-groups from the input bitstrings; operations can be performed using any number of variables less than or equal to the number of bits in the bitstring.

Only the bitring minus the remainder of it and the number of variables given in the expression will be evaluated, since only that part can possibly be evaluated using the given expression. For example, if a bitstring of an odd length is given in conjunction with an expression containing two variables, the remaining bit in the input will be ignored.

recent updates

Project updates are coming!


Due to many recent updates to this website, including the new domain name and hosting setup, email setup, and content and stylesheet developments, my repositories have been left alone altogether. This will change soon with updates and many new projects that are coming.

telnet server with sockets and multithreading

Telnet, a text-oriented network protocol, offers many opportunities for learning to program and operate sockets (see RFC 854 for specifications about the Telnet protocol).


This project was created with the intention of better understanding sockets and the Telnet protocol itself. It also offers a way to create a honeypot system for bot detection and logging. Socket-based programming also offers many opportunities to practice developing multithread programs wherein threads could theoretically comprise individual client connections, allowing for the development of a multiuser communication system.

A Telnet server program was created that incorporates both of these concepts, the use of sockets and multithreading. It was created for the purpose of education of these concepts as well as the education of the Python language itself.

The program accepts clients from the main thread and creates a new thread for each connection that is established. A socket is created as the object for each client thread.

Human users—and often robots—are able to connect and type in commands. Many robots have attempted to log in and run shell commands—although there is no login required, and most of the shell commands robots attempt have not been implemented.

Robots, as part of a botnet, will connect and run commands such as root or sh to attempt to log in as root and execute the shell respectively. In order to reduce botnet traffic, I have implemented an automatic IP address ban whenever a suspected robot enters one of these commands.

Although this currently offers few user abilities and little resemblance to a real command-line, this could easily be expanded and modified to more effectively simulate an unprotected shell server. Most work on this project has been placed on the fundamental interface, specifically in the handling of characters sent to the server and the appropriate response to be made, such as a backspace sequence or a previously entered command.

Much more work will have to be made to develop a directory system, but active users can be viewed and could be allowed to interact with a little more development.

working with brainfuck

Both a uniquely named and purposed esoteric programming language, brainfuck is composed of a mere eight commands, making it very difficult to use effectively.


Because of the simplicity of this language, most brainfuck programs will be much larger in terms of file size that their counterparts in other languages. For this reason, many programmers have found ways to optimize code so that it can have a greater usability with fewest possible commands.

Brainfuck operates using a single array on which array elements can hold values ranging from 0 to 255. Arrays may be either unlimited or of size 255, depending on the implementation. There is a single pointer which is located on any one of the array elements at a time.

The pointer can increment or decrement the value within the current array element, and the pointer can be incremented or decremented to a new position on the array. Both values wrap around between 0 and 255 once the value goes out of this range, depending on the implementation.

This language also comes with a simple while loop that operated based on whether the value of the current array element is zero or not. If the value is zero, then the loop wil be discontinued.

A project on which I am working is a Python program that accepts ASCII character input and creates a brainfuck program which will output those characters when interpreted.

The program creates multiple segments of code for each character, then it finds the smallest segments and combines them into a single program.

This gives the effect of organization. For example, using a code segment length of eight and four code segments per line, the program will output the following code for a program that merely outputs hello:

++++++++ [>++++++ +++++++< -]>.—-.
+++++++. .+++.

Because of the way most brainfuck interpreters parse code, comments are usually quite flexible. Comments can be placed throughout brainfuck code as long as no brainfuck commands are used:

++++++++[>++++++++<-]>+.    print "A"

Because the specifications for the brainfuck language are not defined well, many brainfuck interpreters do not run code the same way. However, I have created an interpreter which follows the same rules as the majority of interpreters I have seen.

Some parts have been modelled after Sebastian Kaspari's interpreter, such as the use of the filter function to clean up input and the buildbracemap function, which appears as get_map in my code.

Although many brainfuck programs will rely on ASCII input and output, there is also the possibility to create programs that operate merely with program-specified numbers. Mathematical programs can be created which use predefined outputs and even give output as the number itself and not ASCII characters.

This makes programming brainfuck much less complicated for certain types of programs as long as the interpreter allows output of values.

For example, the following program was created which can multiply a list of numbers and output the product as the value itself and not the necessary ASCII characters. This program, as long as it is interpreted with an interpreter which allows value output, will give the product of these numbers once it completes:

>+++>++++		set the array of factors
[			begin the multiplication loop
    [>>[>]+[<]<-]	expand the ending item into an array of ones
    <-			decrement the preceding item
    [>>>[+>]<[<]<<-]	increment each item in the array of ones
    [[>]<-<[<]<+>>]	sum the incremented array to form the product sum
    [<+>-]		move the product sum to the left by one position
]			exit the multiplication loop if no factor remains
>.			output the final product sum

This program can also be used with the addition of a preceding loop to multiply the same number a specified number of times, which outputs it as a power of the specified exponent:

>+++>++++		set the exponent and base respectively
<-			decrement the base
[			begin the base duplication loop
    [>+>+<<-]		make two copies of the base and remove the initial base
    [[<+>-]>]		move the copies to the left by one position
    >-			decrement the exponent
]			exit the base duplication loop if the exponent is zero
[[<+>-]>]		move the copies to the left by one position
[			begin the multiplication loop
    [>>[>]+[<]<-]	expand the ending item into an array of ones
    <-			decrement the preceding item
    [>>>[+>]<[<]<<-]	increment each item in the array of ones
    [[>]<-<[<]<+>>]	sum the incremented array to form the product sum
    [<+>-]		move the product sum to the left by one position
]			exit the multiplication loop if no factor remains
>.			output the final product sum

While the language has relatively few practical purposes, it has proved a challenge to create some programs with it. Many kinds of programs can be created which manipulate the array in ways other than merely printing strings of characters.



There is a guestbook available on this site for visitors. Please leave a message!