Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Sunday, April 13, 2025

Slow Query Monitoring in MySQL and MariaDB

To enable slow query monitoring in MySQL or MariaDB, run these commands in your client:

SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 0.5;

This activates the slow query log and sets it to capture any queries taking longer than 0.5 seconds. You can adjust this threshold based on your performance requirements.

Slow queries will be logged to some file like:

/var/lib/mysql/*-slow.log

You can check or change that with:

SHOW VARIABLES LIKE 'slow_query_log_file';
SET GLOBAL slow_query_log_file = '
/custom/path/slow-queries.log';

To make these changes permanent, add these lines to your my.cnf/my.ini file:

[mysqld]
slow_query_log = 1
long_query_time = 0.5
slow_query_log_file = /custom/path/slow-queries.log

To analyze slow queries, use:

mysqldumpslow /custom/path/slow-queries.log

Wednesday, April 24, 2024

Voyager Manager v0.1

I've written around seven programs for my HP 12c. I've manually combined them into a big "multiprogram" which starts with a jump table: a bunch of GTO commands, each one jumping to the entry point of one of the actual programs. The reason for that is that the HP 12c has only one contiguous program area. Fortunately, the calculator allows you to manually execute a GTO command before pressing R/S to start the execution. But instead of having to remember the starting address of each program, I just put them on the GTO instructions on the jump table so I just need to manually do GTO 003 and press R/S to start the third program, because address 003 has the GTO to the starting point of the third program. 

But managing this multiprogram is very tedious. When a program is placed in a different starting address in memory, all the GTO targets of that program need to be updated and offset correctly to continue working. So I made a program called Voyager Manager that lets me compile any number of programs into one such multiprogram, taking care of the GTOs and the jump table automatically. It works for my programs but it's still a very early version. It comes with GNU/GPLv3 source code, Lua binaries for Windows included, and a library that includes my programs for the HP 12c to get you started.

You can download Voyager Manager from here.

Wednesday, April 13, 2011

Quick note: Why I use Firefox

Although Chrome is a very pretty and fast browser I still preffer Firefox for the following reasons: (obviously I will not try to explain why I don't use IE)
  1. Loading custom spell-checking dictionaries to Firefox allows me to spell-check both Greek and English at the same time, without even switching dictionaries (someone has already made a combined dictionary for that).
  2. There is a master password to protect the passwords in the password manager of Firefox. The Chrome guys for some reason refuse to implement that giving some ridiculous explanation on why they don't want to do it. (I can explain why it's ridiculous if someone disagrees)
    BTW that makes Firefox Portable a great choice in portable browsers.
  3. Firefox can change proxies easily while Chrome depends mostly on the system wide proxy settings (like IE) or some, not so practical, tricks.
  4. TorButton is only for Firefox.
  5. When I am making a webpage, the first browser on which it works as expected is Firefox. I've had some minor problems with Chrome when, for example, I was trying to implement a CSS sticky footer. Chrome would make the page a little bigger than the window thus showing a vertical scrollbar although there was no reason. Maybe it was some mistake I did but I had no problems in Firefox.
    For some reason Firefox, usually, is the one that shows things as I expected them to be rendered, despite Chrome being more standards compliant.
  6. Nothing compares to FireBug when you develop stuff... NOTHING.
  7. Although I still haven't done some serious tests, by my personal experience I find Firefox more responsive, compared to Chrome, when many tabs are open. But, usually, people don't work with 25+ tabs open at the same time like I do, so Chrome will be more responsive for normal usage.
Why not Opera? They stick to the standards more than anyone. These guys are good programmers, I can't deny that. But I really like having open source software when I'm using it to communicate with banks etc. Also some of the points above apply to Opera too.

Hey this note wasn't that quick after all...

Friday, January 16, 2009

Email sanitizer-extractor in Lua

Yesterday a friend asked me to write a little script that reads a file and outputs every email it reads in another file, discarding any duplicates. After making the program he told me that he was searching the Internet and couldn't find something similar so I should upload it somewhere just in case someone else needs it.

To make it more interesting I managed to make it a single call program: everything is defined inside the arguments of a single call. In fact there are two calls: the first returns an object, a function of which is immediately called. Anyway here is the code:

io.open("output.txt","w"):write((string.gsub(" "..io.open(((arg or {})[1] or "input.txt")):read("*a").." ",".-([%w%.%-_]+@[%w%.%-_]+).-",function (email) email=string.lower(email) print("EMAIL: '"..email.."'") emails=emails or {} for index,emailseen in ipairs(emails) do if emailseen==email then return "" end end table.insert(emails,email) return email.."\n" end)))

Now let's break that up and put some comments, shall we?

io.open("output.txt","w"):write( --io.open opens a file in write mode and returns the file handle which instead of being stored in a variable is immediately used by calling it's filehandle:write function.

(string.gsub( --string.gsub will finally return two arguments: the email list, one per line, lowercase, and without duplicates and the number of replacements it did. The first argument is our output. I can discard the second by putting the function call, therefore the returned argument list, into parentheses. In Lua print((5,"kostas","klapatsimpala")) will just print 5.

" "..io.open(((arg or {})[1] or "input.txt")):read("*a").." " --This is the first argument to string.gsub. like we did before, we open a file in read mode and immediately use the returned handle to do a full read of the file. A tricky part is the "(arg or {})[1] or "input.txt"" part. If you call a lua script with extra arguments then the arg table will be created by Lua. If it exists then the "arg or {}" part will evaluate in "arg" (if on the left side of an "or" is a true value then "or" simply results in that) and then "(arg)[1]" will return the first variable which is a custom input filename. That filename "ORed" with "input.txt" will simply return that filename (since any strings are true values for Lua, so OR will evaluate in the left argument). If you didn't call the script with any arguments then the arg table will not exist, thus the "(arg or {})" part will result in a newly created empty table. Of course if you index it's first cell you'll find nothing, so the "({})[1] or "input.txt"" will result in "input.txt" (if "or" finds a false or nil value on it's left it will simply return the value on it's right). Finally I add two space characters: one to the start of the read data and one to the end. These are added so that the pattern matching I use will apply to any emails exactly at the beginning or exactly at the end of the read data.


,".-([%w%.%-_]+@[%w%.%-_]+).-" --The second argument is the pattern. I am breaking up the whole text in the following way: any number of any characters (as less as possible) followed by any number of email allowed characters (as much as possible), followed by @, followed by any number of email allowed characters (as much as possible), followed by any number of any characters (as less as possible). The "email allowed characters" are: alphanumerics, dot, dash, underscore). From this pattern I want to capture just the email part.

,function (email) --Now this is the best part. An anonymous function. It is created without being stored in a variable (which would give it a name) and immediately used as an argument to string.gsub. This function accepts a single argument: email. string.gsub will call it for every match with the capture (the email) as an argument.

email=string.lower(email) --First of all we turn the email to lowercase

print("EMAIL: '"..email.."'") --Debugging message...

emails=emails or {} --Remember what we said. If the left argument is true (not false and not nil) then it is returned, so if the emails variable has already been defined nothing will happen because emails=emails will be executed. If the emails variable is not defined (is nil) though, then "or" will return it's right argument therefore emails={} will be executed and emails will be initialized as an empty table.

for index,emailseen in ipairs(emails) do --For every already seen email do:

if emailseen==email then return "" end --If this already seen email is the same with the new capture then just return "" so that the whole match will be replaced by nothing. Remember that although the capture is just the email, the match includes the email as well as the preceding and the following characters.

end --end for.

table.insert(emails,email) --If we managed to get here then this email capture is seen for the first time. We insert it in the emails table.

return email.."\n" --and finally we return the email capture (lowercase) followed by a newline. This will replace the whole match.

end --end of the anonymous function

) --closing of string.gsub

) --that's the second parentheses for string.gsub (to discard the second returned argument)

) --closing of write.


That's all. I seem like it is working but I haven't done any extensive debugging.

Thursday, July 31, 2008

Big table implementation in Brainfuck

In the past I had found an efficient way of implementing tables on the Brainfuck array. There were already some table implementations which used at least 2*n Brainfuck cells for storing an n sized table. My implementation needed only n+4.

Also, all known implementations had a limit of 256 cells (Or equal to the size of a cell on the Brainfuck array. For the rest of the post I will assume that the cell size is one byte).

During my road-trip to Spain, based on my old implementation, I found a new one that can use multiple indexes to implement tables of ANY size on the Brainfuck array. Additionally the table cell size can be any multiple of the Brainfuck array's cell size.

It uses a format similar to my old implementation: a head moving through the table while decreasing the index it carries, passing table data over it, until it finds the correct position,the it does it's job (read/write) and then it returns in the same way but using a copy of the index.

For a table with n cells of size k each the form of the header is:

  • k empty cells: When the head need's to move to the right, it will have to move the first k cells on it's right in these empty cells before moving itself k positions to the right (thus moving itself to the next indexed position)
  • n index cells: Before starting a read or write operation you will have to store the index here. The leftmost index is the most important. For example if the maximum possible value for an index is 9 (instead of 255) and you use two indexes, to access the 15th cell you would have to use 1 for the left index and 4 for the right index (not 5 because the numbering starts from 0).
  • k data cells: To write to the table you will have to put the data in these cells. If you read from the table, after the end of the read operation the read data will be here. These cells MUST be cleared before starting a read operation.
  • n empty (index) cells: While the index cells are reduced, these cells are increased so that, when the seek operation finishes, they will hold a copy of the original indexes which will be used for returning the head to the beginning of the table.

After the header the table data is assumed to be laying. n*k cells in total. For example for a size 400 table with 2 bytes per cell they would have this form:
Data 1 of index 0,0
Data 2 of index 0,0
...
Data 1 of index 0,255
Data 2 of index 0,255
Data 1 of index 1,0
Data 2 of index 2,0
Data 1 of index 1,1
Data 2 of index 2,1
...
...
Data 1 of index 1,143
Data 2 of index 1,143

So you will need 2*k+2*ceil(log256(n))+n*k cells on the Brainfuck array to store a table with n, k-sized cells. (ceil(log256(n)) is the number of the indexes)

Therefore the code needed to write or read from the table depends on n and k. I actually wrote some metacode that provided with n and k produces the corresponding code. I then turned the metacode into a Lua script. It's not well written but I believe that it works. I tried the following cases:
  1. Writing two values to a table with n<256 and k=1 and then reading them back.
  2. Writing two values to a table with 256<n<256^2 and k=2 and then reading them back.
and everything worked fine.

If you want to try the script yourself you download it from here.

Here is some example code:

n<256 k=1
Write:
>[->>+>[-<<<<+>>>>]<[->+<]<[->+<]
<[->+<]>]>>>[-]<<[->>+<<]>[-[-<+>
]<<<<[->>>>+<<<<]>>>]<<<
Read:
>[->>+>[-<<<<+>>>>]<[->+<]<<[->+<
]>]>>>[-<<+<<+>>>>]<<<<[->>>>+<<<
<]>>>[-<[-<+>]>[-<+>]<<<<[->>>>+<
<<<]>>>]<<<

256<n<256^2 k=1
Write:
>>[->>>+>[-<<<<<<+>>>>>>]<[->+<]<
[->+<]<[->+<]<[->+<]<[->+<]>>]<[-
>>>+>>[-<<<<<<+>>>>>>]<[->+<]<[->
+<]<[->+<]<[->+<]<[->+<]>>-[->>>>
[-<<<<<<+>>>>>>]<[->+<]<[->+<]<[-
>+<]<[->+<]<[->+<]>>]<]>>>>>[-]<<
<[->>>+<<<]>>[-<[-<+>]>[-<+>]<<<<
<<[->>>>>>+<<<<<<]>>>>>]<[-[-<+>]
>[-<+>]<<<<<<[->>>>>>+<<<<<<]>>>>
>-[-<[-<+>]>[-<+>]<<<<<<[->>>>>>+
<<<<<<]>>>>>]<]<<<<
Read:
>>[->>>+>[-<<<<<<+>>>>>>]<[->+<]<
[->+<]<<[->+<]<[->+<]>>]<[->>>+>>
[-<<<<<<+>>>>>>]<[->+<]<[->+<]<<[
->+<]<[->+<]>>-[->>>>[-<<<<<<+>>>
>>>]<[->+<]<[->+<]<<[->+<]<[->+<]
>>]<]>>>>>[-<<<+<<<+>>>>>>]<<<<<<
[->>>>>>+<<<<<<]>>>>>[-<<[-<+>]>[
-<+>]>[-<+>]<<<<<<[->>>>>>+<<<<<<
]>>>>>]<[-<[-<+>]>[-<+>]>[-<+>]<<
<<<<[->>>>>>+<<<<<<]>>>>>-[-<<[-<
+>]>[-<+>]>[-<+>]<<<<<<[->>>>>>+<
<<<<<]>>>>>]<]<<<<

Monday, February 18, 2008

Memory efficient Brainfuck tables

Here is a nice way to implement an indexed table in Brainfuck, using only n+4 memory for n table cells. I will soon release a new version of FBF that uses this implementation instead of the old one which used 2*n+3. (Well maybe not... I am bored...)

The table has the following structure:

0 I I D (0) (1) (2) (3) ...
^

For a table with n cells you will need n+4 cells on the Brainfuck array.
( n <= cell size) We start from where the ^ points. The first cell should be empty (zero). The second and third cells contain the index that we want to write to or read from. The fourth cell contains the data that we want to store in the table. If we want to read from the table then we should leave this cell empty and it will later carry the read data. The next cells (0) (1) ... (n-1) are the actual data stored in the table. We'll call the I I D part the "head". It works like this: Move the head to the right place: (the head moves to the right by moving the data of the next cell to the head's preceding empty cell, then moving each of the I I D cells one place to the right creating a new empty preceding cell.)

We will move the head to the right to the correct index:
>[
>>>[-<<<<+>>>>]
<
If we want to write something then we should carry the D cell too: [->+<]
<[->+<]
<[->+<]
>-]

Now we may read:
>>>[-<+<<+>>>]<<<[->>>+<<<]>
Or we may write:
>>>[-]<[->+<]<

Now we will return the head to it's initial position:
[
[-<+>]
If we have read something then we need to carry the D cell too: >[-<+>]<
<<<[->>>>+<<<<]
>>-]
<<

After a successful read the I I cells should be empty while the D cell will hold the read data.
After a successful write the I I D cells should be empty.

The pointer ends at the some place where it was before we used the algorithm, that is to the left of the first I cell.

Here is the code uncommented:

Write:
>[>>>[-<<<<+>>>>]<[->+<]<[->+<]<[->+<]>-]
>>>[-]<[->+<]<
[[-<+>]<<<[->>>>+<<<<]>>-]<<

Read:
>[>>>[-<<<<+>>>>]<<[->+<]<[->+<]>-]
>>>[-<+<<+>>>]<<<[->>>+<<<]>
[[-<+>]>[-<+>]<<<<[->>>>+<<<<]>>-]<<

Saturday, February 16, 2008

Tiny Lua Distribution

Lua 5.1.3 has been finally released. I downloaded the binaries from LuaBinaries only to discover that the Windows version has been compiled with Microsoft Visual C++. That means that one would now need to carry along three files instead of one: the lua interpreter, and lua51.dll and the runtime library for Visual C++ (msvcr80.dll)! I recompiled the source code of Lua with Dev-C++ and now only one file is needed, just like the Linux version! I also compressed the two versions with UPX so that each one of them is around 65KB. You can download these two tiny interpreters from here.

Sunday, January 20, 2008

SEcure PUblic Key TRAnsfer

Internet is perhaps one of the few places where almost everyone (most people have access to it) can express himself/herself. That gives the people great power and thus most governments try to control this free flow of information by monitoring all communications: chat, emails, instant messaging etc, supposedly to prevent terrorism... Whether the governments lie or not, I will not analyze it here. What I really know is that everyone deserves privacy. I can always whisper a secret and no law can prohibit me doing so. The same should apply to my Internet communications. I want to be able to say things to a friend without any government or person been able to eavesdrop or interfere. And this can be done with strong encryption. Encrypted communication is for me one of the best things a computer has to offer compared to a phone. There are two different kinds of encryption: symmetric and asymmetric. Symmetric cryptography is the most known. The algorithms that implement this kind of encryption are not so computationally intensive. It uses only one key which both parts (the people that want to communicate) must already know and this is the main disadvantage. This can be done either during a face-to-face meeting or over another secure channel. But what happens when you have no way of agreeing on a key with the other part? That's when public key encryption (asymmetric encryption) comes in. In asymmetric encryption there are two keys: the public one and the private one. You use the public key to encrypt a message which can only be decrypted by the corresponding private key. So in order to communicate safely with someone you follow these steps:
  1. Each of the two parts generate a pair of public - private keys.
  2. The two parts exchange their public keys over a possibly insecure communication channel.
  3. Now if one part wants to send a message to the other it simply encrypts it with the public key of the other part and then sends it. An eavesdropper cannot decrypt this message because he has not got the private key needed.
But even this type of encryption is not completely secure. One possible vulnerability is exploited with a man-in-the-middle attack. Here is a possible scenario where Bob wants to talk with Alice while Mario performs a MITM attack.
  1. Bob generates a keypair. (a public and a private key) and sends his public key to Alice.
  2. Mario, who is an employer in Bob's ISP, has already generated a keypair and while the packet with Bob's key is transient he replaces Bob's key with his own (he also notes down Bob's public key).
  3. Alice receives Mario's public key but she believes it's Bob's.
  4. Alice generates a keypair and sends her public key to Bob but Mario replaces it with his own, just like he did with Bob's.
  5. Now Bob wants to send some data to Alice. He encrypts it with Mario's key believing that it's Alice's key and sends the encrypted data.
  6. The encrypted data is peaked by Mario who is able to decrypt them with his own private key. He then re-encodes them with Alice's correct public key and passes them on Alice.
  7. The same thing happens when Alice replies to Bob. Mario is able to eavesdrop on the connection even though both part's think that is secure.
There are, of course, some ways to reveal MITM attacks. One of them involves trusted third parties which are called Certificate Authorities (CA) because they verify that the public keys have been exchanged correctly. In fact whenever you login to your Paypal, email etc account with a secure connection you do make an asymmetrically encrypted connection with that site. But, in order to ensure that there is no man in the middle, your browser also establishes another secure connection to a Certificate Authority (like StartCom) in order to check the integrity of the public key you just received. The connection to the Certificate Authority is also asymmetrically encrypted but the public key of the CA is already embedded in your browser since you downloaded it. So? Are our connections now safe? Well, your bank transactions are secure but the MITM problem remains for other types of communication. What if you want to communicate with a friend with a program that supports asymmetric encryption? You can't use a CA in this case because there can't be someone that knows the public keys of every user you chat with. Let alone that in some cases you might not trust anyone, not even a CA. There are some other solutions to this problem. I read about a protocol called "Socialist Millionaire Protocol" that is used by Off-The-Record Messaging (a secure instant messenger). Here is a copy-paste from http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html regarding the protocol:

While data messages are being exchanged, either Alice or Bob may run SMP to detect impersonation or man-in-the-middle attacks. As above, all exponentiations are done modulo a particular 1536-bit prime, and g1 is a generator of that group. All sent values include zero-knowledge proofs that they were generated according to this protocol, as indicated in the detailed description below.

Suppose Alice and Bob have secret information x and y respectively, and they wish to know whether x = y. The Socialist Millionaires' Protocol allows them to compare x and y without revealing any other information than the value of (x == y). For OTR, the secrets contain information about both parties' long-term authentication public keys, as well as information entered by the users themselves. If x = y, this means that Alice and Bob entered the same secret information, and so must be the same entities who established that secret to begin with.

I tried to understand the algorithm but I couldn't! And I think that it's too complex for no reason... They could use this protocol to achieve the same thing:
  1. Bob knows X and Alice knows Y and they want to compare them.
  2. Bob sends some random data to Alice. Alice does the same with some other random data.
  3. Bob appends X to the end of the data he received and then computes the hash of the new data. Alice appends Y to the end of the data she sent to Bob and computes the hash of the new data. Bob sends the hash to Alice. Alice checks whether the two hashes are the same.
  4. Alice appends Y to the end of the data she received and then computes the hash of the new data. Bob appends X to the end of the data he sent to Alice and computes the hash of the new data. Alice sends the hash to Bob. Bob checks whether the hashes are the same.
I think that this is a much simpler (to understand) protocol that achieves the same things. I also came up with another protocol which guarantees that there is no one eavesdropping. It doesn't detect impersonations, just eavesdroppers. In fact it's not a new one, it's just an improved version of the protocol I used in SePuKTra (which you can download from here but as I said it is not the new version of the protocol). The new protocol is much faster and like the old one it reveals man-in-the-middle attacks by measuring delays that the MITM is obliged to cause due to the nature of the protocol. First of all some symbolisms:
  • H(x) is the hash of x. Any hash function can be used. Take a look at MD5.
  • E(x,k) is the symmetrically encrypted data of x with k used as the encryption key.
  • DE(x,k) is the symmetrically decrypted data of x with k used as the decryption key.
  • PK is the public key of the sender.
  • RDP means Random Data Padding.
  • & is the concatenation symbol (VB-style :-P).
  • len(x) is the length in bytes of x.
The packets that are exchanged with this protocol can be placed in three categories and are all of a fixed length and why we will pad the messages with random data:
  • D: The Data packet. It is composed of 4 parts: len(RDP) & RDP & H(K) & E(PK & data,k)
  • A: The Acknowledge packet. It is composed of 3 parts: RDP & H(D)
  • K: The Key packet. It is composed of 4 parts: RDP & H(A) & k
Each part should run a FSM that executes these steps:
  1. Exchange public keys with the other part and start an encrypted connection.
  2. If you are the part that initiated the connection then set time1=0 time2=inf and jump to step 11.
  3. Generate a random key (k) for a symmetric encryption.
  4. Read data (data) from user.
  5. Calculate E(data,k) and H(K) (where K is the last K packet received).
  6. Note down the current time (time1).
  7. Send a D packet (with the structure described above).
  8. Wait for an A packet.
  9. Note down the current time (time2).
  10. Send a K packet containing the H(A) and the key (k) you used in step 5.
  11. Wait for a D packet and store the encrypted data (data) it contains.
  12. Note down the current time (time3).
  13. If (time2-time1)*2<=(time3-time2) then either there is a MITM or you connection is really unstable.
  14. Send an A packet containing H(K).
  15. Wait for a K packet and store the key (k) it contains.
  16. Show DE(data,k) to the user.
  17. Jump to step 3.
The two parts should communicate in this mode for some time and then they may switch to normal communication using the same public keys. Let's see how this works. While Bob chats with Alice the program includes the PK of Bob in every message he sends. Normally Mario would try to replace this PK with his own in order not to be discovered by Alice. But because the D packets contain the PK encrypted with a random key this replacement cannot be done immediately. So Mario has to withhold the D packets until the K packet arrives form Bob. This delay is visible to Alice because (time3-time2) becomes around 4 times bigger than (time2-time1). Mario could make this delay seem natural by artificially increasing (time2-time1) by delaying to send A packets to Alice but doing so would create even more delay on the side of Bob! So Mario can trick one of the two parts that the delays are natural but never both! In order to trick them both he might want to try and send A packets before receiving the D packet and K packets before receiving A packets (in order to create "negative" delays to both sides) but this cannot be done because every packet should include the hash of the very previous packet. That's all for now. I will try to upload some sketches that visualize what I wrote. I am waiting for your comments!!!

Saturday, December 15, 2007

Pattern matching

This week I used for my first time (at least seriously) the pattern matching functions of Lua. I am amazed of how powerful they are! I made two programs using them.
  1. A program that parses the stdout of the finger command (which is issued for the name of all subdirectories of /home/ ) and then issues an id command for each user on the server of my university. This way I made a 250KB textfile containing usernames, realnames, registration numbers, emails and years of registration; just by organizing information that is normally available by using these two commands. Of course this program in it's present form works correctly only for my university...
  2. A simple crawler. After making the main crawler part I tried to find something more useful to collect than emails but I came up with nothing so I made it seek email addresses. (but I hate spam :-P )
Here is an example:
for u,n in string.gmatch(data,"Login: (%a+)%s+Name: (%a+ *%a*)\n") do This is how you start a for loop that will iterate for each username and realname pair that the output of the finger command contains. I uploaded both files (along with Lua interpreters for Linux and Windows and the Luasocket which is needed by the crawler) and you can get them by clicking here. In case you want to run the first program you should upload steal.lua and lua5.1 to a Unix system and then run something like this: ./lua5.1 steal.lua To run the crawler simply drag crawler on the appropriate Lua interpreter.

Saturday, November 17, 2007

Easy Keyboard Layout

The QWERTY keyboard layout (the one that you probably use every day) was made mainly to avoid stuck pairs of typebars in typewriters. Of course this is not a problem with modern keyboards and that makes the QWERTY layout a bit inefficient (at least for the right handed people). For example many words can be typed by using only the left hand while there are fewer that can be typed with the right hand only. The best case would be to have both hands type alternating keystrokes so that you can move one hand in place while you are striking a key with the other.

There are other keyboard layouts too which try to address some of these problems. One the most famous is the Dvorak keyboard which is probably better than QWERTY.

Anyway, to cut a long story sort, I wrote, before one or two days, a program in Lua that would try to make an optimized layout based on three criteria:
  1. Letters that appear next to each other often in English text should be far from each other on the keyboard so that the two hands can press them alternatively.
  2. Characters that appear often with a distance of two characters (like T and E in the word "the") should be close to each other so that that each hand moves as less as it is possible during the alternations.
  3. The most used character should be close to either the third or the seventh key of the second row (where the D and the J lie on QWERTY keyboards) because that's where I put my middle fingers. :-P
I run this program with LuaJIT (because I really needed more speed) and it came up with this layout:

Z V M L W D A I G Q
X H N R S T E O K
J U C F Y P B

Today I bought a keyboard (the cheapest I could find) and started switching the positions of the keys to turn it into this:
(the photo is outdated. The P and B should be switched)
I still haven't tested it because I bought a PS/2 keyboard while my laptop hasn't got a PS/2 port. So I am waiting to test it to a friend's PC tomorrow.

Of course to use this keyboard you will need to notify the system of the different letter positions. I made a file that can be loaded with xmodmap in Linux to use this keyboard. I will also do the same with Microsoft Keyboard Layout Creator so that Windows will be able to recognize my layout.

I won't upload the program's code yet because I am constantly changing it. If you really want it then just leave a comment asking for it and I will upload it. You might also want to try Kiwi: a program written in C that will create custom keyboard layouts. It looks like a great program but I haven't actually tested it yet.

Amazing fact: Just by changing the position of the letters on a keyboard you can create more than 403,291,461,126,605,635,584,000,000 different layouts.

Sunday, October 14, 2007

FuckBrainFuck v1.7.1

Today, while improving AskWise I had to look at a part of the source code of FBF and, luckily, I found a terrible mistake in it. The SET command was supposed to set a cell in the Brainfuck array to a specific value. But in addition to this, because of the bug, it zeroed the very next cell. I do not know how that stupid bug occurred! I wonder how did the compiled FBF programs work... :-( Click here to download the new version.

Tuesday, September 18, 2007

Revised FuckBrainfuck Documentation

The current version of the FBF compiler is 1.7.0 and came along with the second revision of its documentation. I recently noticed that the documentation was full of mistakes and I also had forgotten to list some commands so I corrected it and now you can download the zipfile with the new documentation. The zipfile contains the compiler, the documentation, seven example programs and the Lua interpreter for Windows and Linux which is needed in order to run the FBF compiler.

Monday, September 10, 2007

Infon


Infon is an online multiplayer game. You program the brain of little bugs witch try to survive in an arena by eating food, evolving and multiplying. To play you only need a telnet program. To watch the game though you will need to download the graphical client. Using your telnet program you upload the brain on the server and it executes it. Of course there other games like this like Droidbattles but what makes it different is that it is an online game and it uses my favorite language. Yes, you program the bugs in Lua!

I made a simple brain today which worked quite well. If you know any programming language then it will be easy to learn Lua and try this wonderful game! Click here to go to the website of Infon.

Have fun and if you create a nice brain, challenge me... ;-)

Saturday, August 25, 2007

Lua VS the rest: 1-0

(This will go through a story before ending up to the Lua programming language. Sorry but I felt like writing about myself a bit.)

I've started programming (if you can call DOS batch files programs) when I was 11. My first "program" was a wrapper that was supposed to make floppy disk formatting easier by calling format with some arguments and an optional volume label (I think that I had named it KAFmat). What I liked about files? Nothing. I just had no other choice at that time (I had no idea how I could use QBasic, I barely spoke English after all).

After 2 years a family friend gave me an verbatim CD of Visual Basic 6.0. At first I was only playing with putting buttons that did nothing on a form but soon I started making some programs (one year after I made Logicrypt). I continued programming with Visual Basic for about 4 to 5 years while at the same time I tried some other languages like Pascal, Basic, C++. I also tried and learned quite well Plua (=Palm Lua) which I liked a lot because of its great syntax and ease of programming and the fact that it was a complete IDE which I could use on my old Palm Zire.

But, not before a year, I completely uninstalled Windows and Ubuntu took their place. Of course Visual Basic doesn't run on Wine so I had to find an alternative. At that time I was taking Java and C lessons on my university but I never really liked any of these languages because I find them too tricky for daily use: Java is not lightweight at all while C need too much writing for simple programs. I tried Gambas which is like Visual Basic but I stopped using it because it creates executables for Linux only (but is a very good programming environment nevertheless). So I thought that it would be easy to learn Lua since I already knew Plua.

And so I did. I now program mostly in Lua. It is a very powerful language and suitable for daily use. If you have an idea then you simply open a notepad and write some Lua code which will easily run on Linux and Windows. The code is interpreted by the very lightweight and portable Lua virtual machine which fits easily even on a floppy disk. The virtual machine can either run the source code or the compiled bytecode (which you can distribute if you do not want to show the source code of your programs). The virtual machine doesn't support GUIs or sockets but this functionality can be added with the wxlua and the (great) LuaSocket libraries. You may also use LuaGL for OpenGL 3D or 2D Graphics.

I have only published one Lua program until now: FuckBrainfuck

For more info on Lua you may check its entry on wikipedia or go directly to its website by clicking here or at the title of this post.

Tuesday, August 21, 2007

FBF 1.7.0


Brainfuck is a very beautiful esoteric programming language with only 8 commands. You can make any algorithm you can think of on this language but in most cases it is very hard to do so. In Brainfuck you do not have variables, functions, constants and many other convenient features that most programming languages have. You only have an array with byte sized cells (some implementations allow for other sizes too) and a pointer. Initially all cells in the array are equal to 0 and the pointer points to the beginning of the array. Now you can only issue 8 commands that are symbolized by one character and take no arguments: "< > - + , . [ ]". "<" decreases the value of the pointer by one, while ">" increases it. "-" decreases by one the value of the pointed cell on the array, while "+" increases it. "," read a character from the keyboard and stores it in the currently pointed cell, "." prints to the screen the character stored in the currently pointed cell. "[" will jump to the command after the corresponding "]" only if the currently pointed byte equals to 0. "]" will simply jump unconditionally to the corresponding "[". That's all. With this commands you can make any calculation but it will be very hard. You can see Brainfuck as a nice brainteaser; just think of an algorithm and try making it in Brainfuck. For more information on Brainfuck read this article or visit the open directory project for Brainfuck related pages.

FuckBrainfuck
(FBF) is a programming language which I made. It compiles directly to Brainfuck code and supports many features found in common programming languages so it makes creating a Brainfuck program easier. Of course you are not actually programming in Brainfuck but you will be able to create very complex Brainfuck programs. The FBF compiler is written in Lua (which is one of my favorite programming laguages) and will run on both Linux and Windows. In the zipfile you can find an extensive documentation, the source code of the compiler (GNU/GPL version 3 license), Lua interpreters for Windows and Linux and some example programs in FBF.

Here is a small program written in FBF:
#DIM char
READ char
UNEQ char '.'
IFNOTEQ char 'z'
INC char 1
END
IFEQ char 'z'
SET char 'a'
END
PRINT char
READ char
END

You can download FuckBrainfuck by clicking here.

Popular Posts