Sunday, July 29, 2012

Some Tech Humor

Another not-so-technical post. I've come across a lot of rather funny tech-related comments and web pages and there are some that I find very clever, specifically jokes made with code. So I will share some of them.

Some stuff in C
// Sometimes I feel like the compiler ignores my comments

#include <stdlib.h>
#define TRUE random()%2

int random(void) {
    return 4;
}

Malloc everything, free nothing!

COBOL
PERFORM SEX WHILE MAN EQUAL TO TASK

REPEAT
 ...
UNTIL THE-COWS-COME-HOME

Java
Exception up = new Exception("Something is really wrong.");
throw up;

} catch (PartInitException pie) {
// Mmm... pie
}

 try {
 //...
 } catch (SecurityException sex) {

Miscellaneous
double penetration;

Disallow: /harming/humans
Disallow: /ignoring/human/orders
Disallow: /harm/to/self

If I come across anything else that I find funny, I'll add it here.

Friday, July 27, 2012

Technical Speak (some thoughts and advice)

This post is not going to be technical so much as I really want to write about some tech things people say that are either completely wrong or just down right annoying. So take this how you will, but this is an opinion piece.

Something I once did before I knew much about computers but now that drives me crazy when I hear it, is when people talk about Java and call it Javascript or visa versa. Let us get a few things straight. Java is not related to Javascript nor the other way around. Javascript is a scripting language based on ECMAScript whereas Java is an interpreted language developed by Sun Microsystems. While Java can be used as a web technology, it is not the same as Javascript and while they have some similar naming conventions, any real depth into some code would reveal they are very dissimilar. So stop mixing them up, it is frustrating.

Another irritating point for me was created by the media, "Mac vs PC." The real goal of this is Mac OS vs Windows. Mac computers are PC's, as PC stands for personal computer. Furthermore, Mac computers can run Windows and if you're crafty, you can run a Mac OS on another PC, virtual machines being the easiest to get things going. Also some people throw Linux into the list. Well, OS X is Unix based as well. So they have some similar things to them. As to which is better, all three of them suck. It is just a matter of picking which one sucks less at what you personally need to accomplish. None of them are good at everything no matter what they claim.

Overuse of acronyms. In the technical world, many acronyms exist. Many acronyms overlap and it depends on what you are talking about. Overuse of acronyms in situations where it is not necessary is annoying and even a tech geek can get lost in such conversations. Granted there are exceptions where some technologies are explicitly referred to their acronym based name because some of the names are long and annoying. Some examples are XML (eXtensible Markup Language), HTML (HyperText Markup Language), or even php (Personal Home Page/Hypertext Preprocessor [it has changed over time]). Choosing to use all those acronyms in an environment outside of a situation that deals directly with such things is annoying, confusing and not many people can follow clearly. Use words.

Being able to navigate a website does not make you tech savvy, same goes for navigating software. I am relatively tech savvy and I get lost on so many websites and various user interfaces. One annoying example is of Microsoft Office. They keep changing the interface, and while I know what I want to do, I can spend a lot of time looking for various options. These things are esoteric and not standardized. While many try to keep similar conventions in an attempt to create better ease of use, they do not have to. Reliance on people trying to make similar and familiar interfaces is not possible.

Do not use tech terms you do not understand. If the media is to teach us anything, let it be this. For example the famous CIS line, "I'll make a GUI interface in visual basic, see if I can track an IP address" (GUI pronounced "gooey"). Taking this I would have to respond, okay, I will make an OS in Piet, see if I can make a super computer. Despite the lack of need to sum up why this is dumb, I am going to do it anyway. A GUI is not necessary for any of this. A good deal of tools for sniffing are done in command line interfaces because there is no point in the extra computational time and effort going to making a pretty window. Visual Basic is a dumb choice. I don't even know if you could make a sniffer from VB. If you can, it is probably some random .NET feature that is a waste of time. Now you do not "track" an ip, you can trace a route. Tracing would be following something along its path. That is a small thing to pick at, but tracking an ip would be like sniffing just that ip. Tracing would be finding the origin.

Using tech terms from one thing for a separate case.When drawing a comparison it is fine. However, using that comparison like the cases are equal is usually not fine.

Comparing things on levels that they are not comparable. I am sure at some point you have come across things like Perl vs Python, where they argue about dumb things like which is easier to read or application. Seeing as how Perl was more so made for text processing and Python is more of a general purpose language, they are obviously not going to be good at the same things. Benchmarking comparisons are one thing, but arguing about readability or which way of doing things is better is dumb because it depends on the application and the person.

Skids. Script kiddies. People that claim to hack when they are using premade tools without knowledge of the underlying innerworks of how or why things work they way they do. Downloading things like custom firmware to break a game system or opening up a tool to do some network scanning. Some of these can be dangerous if you do not have some understanding of how they work. In this light, the use is not that of a tool but a black box effect. Someone puts something in and gets the desired result out without understanding what just happened. So not everyone that uses these tools are skids or something to that effect, some actually understand in general how they work and use a premade tool to build something else faster.

So those are just some thoughts and opinions based off of things I have heard people said that just really catch me the wrong way and I have seen them criticized for saying such things as well. An easy way to keep yourself from saying something that will annoy others, whether you are right or wrong, is to remember you do not need to prove anything to anyone what you know, because you already know you know it.

Sunday, July 22, 2012

IRC Bot (logbot)

After my first post on IRC bots, I decided to make a bot for logging a chat that was a bit better designed than the one I posted. It is far from perfect, however it will write formatted logs to a file for you, won't sit around if it is kicked and if it sees a message it cannot format, it will log the raw data. Also to keep in mind, it only joins a channel ofter the motd finishes with a certain number code. If there is no motd or it does not send the right number code it won't join. The reason for this is I just wrote the thing today and don't have the time to check all possibilities. So use it as a skeleton and develop on it further. Or ignore it and move on with your day. All descriptions will be commented in the code.

#!/usr/bin/env python
# Import all the packages we will be using
import logging
import socket
import ssl
import os
import sys
import re

# Some global variables for configuration
HOST = "irc.69megabytes.com"
PORT = 6697
NICK = "PyLogBot46"
CHANNEL = "#allthefallen"
SSL = True
FLOG = os.path.join(sys.path[0], "ircbot.log")
PWD = "supersecretpassword"
# This is for use later on to know when to join the channel and do it only once
notInChan = True

# Regex parsing of a standard IRC message
def parse(data):
    temp=re.match(r"^(:(?P<prefix>\S+) )?(?P<command>\S+)( (?!:)(?P<params>.+?))?( :(?P<trail>.+))?$", data)
    if temp:
        temp=temp.groupdict()
    return temp

# Where the magic happens
if __name__ == '__main__':
    # Set up the logging format
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(message)s', datefmt="%Y-%d-%m (%H:%M:%S %Z)", filename=FLOG)
    # Message format strings so we can easily alter them
    format_privmsg = "{1} <{0}>: {2}"
    format_notice = "(notice) <{0}>: {1}"
    format_join = "{0} has entered {1}"
    format_nick = "{0} is now known as {1}"
    format_mode = "{0} set mode {1}"
    format_modes = "Mode set {0}"
    format_kick = "{0} kicked from {1} by {2} ({3})"
    format_srvmsg = "-!- {0} {1} {2}"
    try:
        # Create socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # Set up SSL if necessary
        if SSL:
            s = ssl.wrap_socket(s)

        # Connect to the server
        s.connect((HOST, PORT))

        # Authenticate
        s.send("NICK " + NICK + "\r\n")
        s.send("USER " + NICK + " www.anarchy46.net PY :Python LogBot\r\n")

        # Main loop
        while 1:
            # Reset information received and processed
            data = ""
            info = {}
            # Retreive data 1 byte at a time, stop at newline
            while data.find("\n") == -1:
                data += s.recv(1)
            # Remove unnecessary whitespace
            data = data.strip()
            # Parse the raw data
            info = parse(data)
            # Privmsg handler
            if info['command'] == "PRIVMSG":
                logging.info(format_privmsg.format(info['prefix'], info['params'], info['trail']))
            # Notices
            elif info['command'] == "NOTICE":
                # If to self from someone
                if info['params'] == NICK:
                    # To quit properly
                    if info['trail'] == PWD:
                        s.send("QUIT :Done logging.\r\n")
                        break
                    # So we don't log the password
                    logging.info(format_notice.format(info['prefix'], info['trail']))
                # Server notices
                else:
                    logging.info(format_srvmsg.format(info['prefix'], info['params'], info['trail']))
            # Respond to server pings (no need to log)
            elif info['command'] == "PING":
                s.send("PONG " + info['trail'] + "\r\n")
            # Someone joins
            elif info['command'] == "JOIN":
                logging.info(format_join.format(info['prefix'], info['trail']))
            # Someone changes nick
            elif info['command'] == "NICK":
                logging.info(format_join.format(info['prefix'], info['trail']))
            # Modes
            elif info['command'] == "MODE":
                # Normal mode changes
                if info['trail']:
                    logging.info(format_modes.format(info['trail']))
                # Modes for self (set by server)
                else:
                    logging.info(format_mode.format(info['prefix'], info['params']))
            # Someone gets kicked
            elif info['command'] == "KICK":
                # Quit if it's the bot
                temp = info['params'].split(' ')
                if temp[1] == NICK:
                    logging.info("Kicked from channel.")
                    s.send("QUIT :Bye bye...\r\n")
                    break
                # Log everyone else being kicked :D
                else:
                    logging.info(format_kick.format(temp[0], temp[1], info['prefix'], info['trail'])
            # Special server messages
            elif info['command'].isdigit():
                if info['trail']:
                    logging.info(format_srvmsg.format(info['prefix'], info['command'], info['trail']))
                else:
                    logging.info(format_srvmsg.format(info['prefix'], info['command'], info['params']))
                # End of MOTD
                if notInChan and info['command'] == "376":
                    s.send("JOIN " + CHANNEL + "\r\n")
                    notInChan = False
            else:
                logging.info(data)
    # Abort!
    except socket.error as err:
        logging.critical("Socket error: " + str(err.errno))
        sys.exit(err.errno)

It's not the prettiest of code, but it works. When launching from the command line, make sure to add an ampersand (&) at the end so you don't need to wait for it or leave a window open with it running. Enjoy, and remember this thing only took me a couple of hours to write and sort out some formats.

Saturday, July 21, 2012

Making an IRC Bot

A common question I get from people I know is about making an IRC bot. The problem I run into with people trying to do this is they are usually very new to programming and half the time they are struggling with the basics of simply how to write a program. So before getting into more detail, there are some prerequisites you need to know first.
  • Understanding the programming language syntax you want to use
  • Basic programming
  • Networking knowledge of basic sockets (nothing in depth but more so how network communication should be modeled)
  • Knowledge of the IRC protocol raw (access to an RFC is very useful)

Now f you are still reading, I will assume you at the very least plan on doing the research before actually trying anything. For this, I will be writing it in Python as it is very simple and easy to do. So let us work through this piece by piece.

The first thing we want to do is run our imports so we can have all the modules we need to work with. Rather than using some third party IRC module, we will work with raw sockets because I can and it gives more insight as to what is going on. We need the module for sockets, and regular expressions. We will also import time and I'll get to why later.

import socket
impor re
import time

So now that we have the packages we need, now we need to create a socket object. With a socket object, we can establish a connection over TCP/IP, among other types of socket connections. For our purposes we will use IPv4 and a stream. For this we use the variables AF_INET and SOCK_STREAM. The AF in AF_INET stands for "address family." Now let's create the socket.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Now we have the socket object s. In another post I will explain how to put an SSL wrapper on it to use a secure connection. As for now, just a socket will be used. Now we need to connect to a server.

s.connect((HOST, PORT))

Here the connection info is passed as a tuple, so yes the parentheses are on purpose. In this, HOST will be a string of either the IP address or domain and PORT is the port number you will connect to. Now that the connection is established, we need to send identifying information for the IRC. To simplify things we will have the program sleep for a second as some servers do not let you authenticate immediately and instead send a signal for it. However I do not feel like writing out something to check for that signal right away.

time.sleep(1>)
s.send("NICK MyIRCbotNick\r\n")
s.send("USER MyIRCbotNick anarchy46.net PY :Python Bot\r\n")

Okay, so now that we've authenticated, we will sleep again then join a channel because yet again, cannot join right away.

time.sleep(1)
s.send("JOIN #somechannel\r\n")

Now we set up the loop to read the server data. Because this will go on indefinitely, we will use an infinite loop.

while 1:
    data = "" # Reset data each time
    while data.find("\n") == -1:
        data += s.recv(1) # Receives data 1 byte at a time
    data = data.strip() # No need for leading or trailing whitespace
    print data
    # Watch for and respond to server pings
    if re.search(r"^PING", data):
        s.send("PONG" + data[4:])

Now you have all the code needed to connect to an IRC server, join a channel and stay connected. A few things to keep in mind. The socket is blocking, so the bot will wait on the recv() until it gets some data. Without blocking the program would be too CPU intensive without some extra work. Also note that printing data will print raw IRC data, which is a lot different than the messages you see in a client, and will include control characters like char 1 and 3. Furthermore, there is no error handling or autojoining should the bot be kicked. This is simply a small and poorly made IRC bot that is to demonstrate what is needed to connect to an IRC and I do not recommend this design as a base for a larger scale bot that will be used more often. Sometime later I will divulge a more robust bot that has the purpose of logging an IRC channel or channels.

Friday, July 20, 2012

Generator Expressions vs. List Comprhension

Something I seemed to have always overlooked in Python was generator expressions. A generator expression uses almost the exact same syntax as list comprehension, however instead of square braces [] it uses parentheses (). The difference here is that a list comprehension will create an entire list and put that in memory. A generator expression creates a generator object, which will only give the value when it is needed. So the advantage in a generator is that it will use less resources and still be able to have values like a list. This makes them good for when you need to evaluate a list of items one at a time as you don't need to load a whole list of items up just to process one data value.

After some reading, there are also some improvements that will eventually be moved to list comprehension. One of these is variables in list comprehension are in a global scope where as with generators they are not. This will prevent side effects (altering a variable by accident). You can also pass a generator expression to a function without the need for the parentheses around it as the function parentheses count. However if there is more than one argument needed, it will need the parentheses.

It should also be noted that a generator expression returns a generator object. List comprehension returns a list. This means for functions that manipulate or require an entire list will not work with generator expressions. A quick example would be random.shuffle().

So the idea of when to choose which one to use would be based on knowing when or how you will need to process the values. For single value processing, a generator expression is ideal, whereas list comprehensions are more for when you need the whole list there and ready to go, possibly with a need to manipulate the list itself. You can also use a generator expression to create a list like list comprehension bu placing it in a list(), which won't increase performance.

Sunday, July 15, 2012

Python lambda (some uses)

I previously brushed over a bit about how lambda in Python works. With it, you can achieve a more functional style design. Using lambda, you can pass a function as an argument without defining another function and then passing that function's name. One thing I do not think I fully clarified on is that lambda is functional programming and in functional programming it must always return a value. As such, an if/else is not used in lambda as it evaluates one statement and returns the result. This can be useful for a shorter and cleaner way to use certain built-in functions, primarily the ones that effect lists. They include functions like map, filter and reduce. Functions like these will iterate through a list and apply the function to the items, either making a new list or returning a value based on what was applied. This can be achieved with list comprehension as well, but not for all of them.

So first let us look at the map function. This will go through a list passing the item to the function and then places the return value in the list it will return. So let us take a simple example of getting the second power of a list of numbers without the map function.
def square(thelist):
    returnList = []
    for item in thelist:
        returnList.append(item**2)
    return returnList

As you can see, that is a very specific function and long to write out for something so simple. Now we shall turn that into a single line with a single function call using the map function.
map(lambda a: a**2, theList)

This is much smaller and simpler to use, as well as clear to anyone that knows lambda is a function. We also did not need to write out and define a function, thus reducing something simple to reflect how simple it really is. Now to convolute things a bit with some list comprehension.
[item**2 for item in theList]

In another post I will explain how to pick the most efficient way for doing the desired task, but for now I will stick with the uses of lambda and equivalent ways to write the same thing.

Now let us look at the filter function. What this will do is similar to map, only it checks for a true or false (or an equivalent that will make a true or false) and return the original value. Sticking with a math feel, let us get a bit more complicated and check for every perfect right triangle, perfect being one that has all integers for side, like 3, 4, 5. To do this, we will use the Pythagorean theorem (a2 + b2 = c2), avoiding using the square root as that tends to be more computational intensive.
def perfectTriangle(thelist):
    returnList = []
    for item in thelist:
        a, b, c = item
        if a**2 + b**2 == c**2:
            returnList.append(item**2)
    return returnList

In this function, it requires the list to be in a tuple of 3 items as the sides of a triangle, the c is always the hypotenuse. If you don't know this math stuff, go do yourself some reading. Now let us apply this to the filter function.
filter(lambda (a,b,c): a**2 + b**2 == c**2, theList)

With the lambda function, there is no if required. This is because it is returning a boolean value which will suffice the if/else style. And now the list comprehension version.
[(a, b, c) for a, b, c in theList if a**2 + b**2 == c**2]

Simple enough. In all of these there is a check to see if the value is True or a value that makes an if statement true and return a list where only the values evaluate true for the condition. Easier to understand the code than the worded version I suppose.

Now finally we look at reduce. This one is different from the others because it does not return a list. It "reduces" the list, or condenses the list, based on a condition you give it. Also unlike the others, 2 arguments are used here instead of the original single argument we have been using (of course making a list of tuples like in filter allowed for a multiple argument style while still only using a single list item). For this one, we shall multiply every number together in the list, giving us something similar to a factorial result.
def factorial(theList):
    retValue = theList[0] * theList[1]
    for item in theList[2:]:
        retValue = retValue * item
    return retValue

As you can see, no list is returned. However doing something like this is a pain and if there is no built-in method or optimized module function to use, we can make a cleaner looking version with the reduce function.
reduce(lambda a, b: a*b, theList)

Nice and sweet. There is also the option adding an initializer argument, in that case instead of starting with the first 2 items in the list, it will start with the initializer and the first item as arguments, respectively.

These are just some of the uses for lambda and built-in functions that they can make easier to use. It is best to use them for a functional style of programming and they can be used in functions you define. To do so, you simply call an argument in your function. Here is a quick example.
def transform(f, data):
    return f(data)

This is a useless function that will take a function and an argument, apply the function to the argument and return the end result. You can also make a function generate a function and return that.
def makeFunction(modifier):
    return lambda data: data + modifier

You can achieve similar results with nesting functions. The piratical application of such things is up to your imagination. Through these, there also lies the possibility that coupled with python decorators you can emulate to some level lisp macros should you be creative enough to do so, however limited. Hope this helps someone understand lambda functions and their uses a bit better and once I create a decent enough application of using lambda to a larger extent, I shall post the code. Until then, happy coding.

Saturday, July 14, 2012

Flip a web page

I know there are a lot of people out there that like messing with others, so I got bored and decided to make a quick little bit of Javascript to do that. This will only work in browsers that support CSS3 and is a bit lengthy because certain browsers need their own special tags. So if you want to flip a page someone is browsing, or maybe even yourself, just enter this code in the address bar of the browser to flip a site:

javascript:document.body.setAttribute("style", "transform:rotate(180deg);-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);-o-transform:rotate(180deg);");void(0);

It's as simple as that, the page should be flipped. Also, here's a link to do it, you can set it as a bookmark to make a bookmarklet: flip

Tag Cloud

.NET (1) A+ (1) addon (6) Android (3) anonymous functions (5) application (9) arduino (1) artificial intelligence (2) bash (3) c (7) camera (1) certifications (1) cobol (1) comptia (2) computing (2) css (2) customize (15) encryption (2) error (15) exploit (13) ftp (2) gadget (2) games (2) Gtk (1) GUI (5) hardware (6) haskell (15) help (5) HTML (4) irc (1) java (5) javascript (20) Linux (18) Mac (4) malware (1) math (8) network (5) objects (2) OCaml (1) perl (4) php (8) plugin (6) programming (42) python (24) radio (1) regex (3) security (21) sound (1) speakers (1) ssh (1) telnet (1) tools (11) troubleshooting (1) Ubuntu (3) Unix (4) virtualization (1) web design (14) Windows (6) wx (2)