I'd like to know how to program a hex editor in python, using just tk with the main installation.
(no add ons like wx or any others)
if anyone can help, this would be gladly appreciated.

I'm not really "good" at python yet, so please try to be detailed.
(not reccomended)

thank you in return :)

Recommended Answers

All 10 Replies

Er, what have you managed to do so far? Can you convert strings into hex strings? Such as a hex view of 'Hello world!!!'? Here is the hex values for it if you don't know: '48656c6c6f20776f726c64212121'
Good luck :D
Post if you need help
Also, do a google seach for Tkinter python manual. That'll help

no... I havn't done anything so far... besides the layout... :(
I need some help on the coding.

I am however working on just a simple hex viewer (only hex)
in that scrolled text widget I copied from here.

I'm using this to display the hex value of a spec number of chars:

__all__ = ['ScrolledText']

from Tkinter import *
from Tkconstants import RIGHT, LEFT, Y, BOTH

fdat = open('import.txt','r') #you can rename this...

class ScrolledText(Text):
    def __init__(self, master=None, **kw):
        self.frame = Frame(master)
        self.vbar = Scrollbar(self.frame)
        self.vbar.pack(side=RIGHT, fill=Y)

        kw.update({'yscrollcommand': self.vbar.set})
        Text.__init__(self, self.frame, **kw)
        self.pack(side=LEFT, fill=BOTH, expand=True)
        self.vbar['command'] = self.yview

        # Copy geometry methods of self.frame -- hack!
        methods = vars(Pack).keys() + vars(Grid).keys() + vars(Place).keys()

        for m in methods:
            if m[0] != '_' and m != 'config' and m != 'configure':
                setattr(self, m, getattr(self.frame, m))

    def __str__(self):
        return str(self.frame)

def example():
    import __main__
    from Tkconstants import END
    stext = ScrolledText(bg='white', height=30, width=32, font='Courier')
    stext.insert(END, fdat.read(1).encode('hex')) #set number of chars here
    stext.pack(fill=BOTH, side=LEFT, expand=True)
    stext.focus_set()
    stext.mainloop()

if __name__ == "__main__":
    example()

and I've done alot of research on tk, I have a pdf to help me.

Ah buddy... Okay, let me show you some hints on hex values. Your code has confused me beyond belief xDDD
Okay, here are some basic functions you're going to have to get comfortable using:

int(x [, base])
hex(x)
ord(c)
chr(i)
str.replace(old, new)

Okay, here's how we can use this information. Say we have this string here: 'Hello world' Now, we want to convert this to a hex value, correct? Also, we don't want a nasty string like this: '0x480x650x6c0x6c0x6f0x200x770x6f0x720x6c0x64' Kinda hard to read, right?
Okay, here's how we convert that string into a readable 2 digit hex code

# First off, some background:
# ord(c) will return the ascii value of a character
# That should help in understanding this
# Get rid of the print statements if you want

def tohex(s):
    hexed = ''
    for x in s:
        a = ord(x)
        print(a)
        a = hex(a)
        print(a)
        a = a.replace('0x', '') # Get rid of that ugly '0x'
        print(a)
        hexed += a
    return hexed

tohex('Hello world')

Okay, so now we have a hex representation of that string, right? Well, now you can do your hex editing if needed be. But, we want to go ahead and reconvert that back into a string, right?

# More background:
# chr(i) returns a character based on the number you type
# int(x [, base]) can take two arguements
# Normally, you just want something like int('9') to return an int 9
# However, we are working with a 16 base, not 10 base.
# So, we want to type this: int(num, 16) for our hex values to return
#  that integer we need

def tostr(h):
    string = ''
    # We want every 2 values (Not sure of an easier way to do this,
    # Other than count every other number, and do an index of evens
    for x in range(0, len(h), 2):
        a = h[x:x+2]
        print(a)
        a = int(a, 16)
        print(a)
        a = chr(a)
        print(a)
        string += a
    return string

Okay, so now we can convert it back now. So, running this: tostr(tohex('Hello world')) will now return (along with some ugly print statements you should get rid of after you understand this): 'Hello world' What you can do with this, is understand what exactly you are doing with that hex editor, and actually display in rows and columns those hex values
Good luck :D
(Also, for hex editing files, you want to open them in 'rb' and 'wb', to edit the binary)

I see...
yours works quite differant from mine.
yours looks like it uses the interpreter to display the hex values,
while mine puts the hex values in a scrolled textbox...
just save the code to a .pyw file.
sorry for the confusion :$
thanx for your code btw...
I just learned something new :P

but I got it to read multiple values...
just cange a few parts of the code:

fdat = open('import.txt','rb')
...code...
stext.insert(END, fdat.read().encode('hex'))

WARNING: has a tendancy to freeze when loading large files.

Ah, you misunderstand the code. You call the function, and it will return a string object that you can write. Thus, you can do this:

e = tohex('Hello world')
'''e = '48656c6c6f20776f726c64''''

And then whatever you need to do, in order to display a text string in your GUI (Tkinter, I presume? I have no experience with Tkinter, so I cannot help with that). Ah, and perhaps something to speed up your read times?
Perhaps you can read in only 5~10 lines at a time, and hex that, then do that for the whole file. That should help it out. That's what I usually do

ah.. (FACEPALM) DX<
omg, why didn't I think to do that...
I R Smrt :P XD
thanx

but yea, I use tk... (universal methods)
it's old, but it works. :)
I have wx, and pythoncard...
but I rarly use them. (not everyone has them installed)

and thanx for the tip. :)
I'll use that alot

I fixed up your code a little. :)

def tohex(s):
    hexed = ''
    for x in s:
        a = ord(x)
        a = hex(a)
        a = a.replace('0x', '') # Get rid of that ugly '0x'
        if (a == '0' or a == '1'\
         or a == '2' or a == '3'\
         or a == '4' or a == '5'\
         or a == '6' or a == '7'\
         or a == '8' or a == '9'\
         or a == 'a' or a == 'b'\
         or a == 'c' or a == 'd'\
         or a == 'e' or a == 'f'): #replace values 0 - f with 00 - 0f
            a = ('0' + a)
        a += ' ' #add spaces between hex (looks like an editor)
        hexed += a
    return hexed

fixed this bug:
it returned this:
00 6e f6 0f 06
as this:
0 6e f6 f 6

and it adds spaces so the final hex dosn't look like:
006ef60f06
kinda hard to read like that... heh

Dude, what's up that? It shouldn't be returning '0' for hex(ord('\x00')). It will return '0x00'.

EDIT:
After relooking at the code snippet on my computer, I realize that it does not return what I thought. xD It does indeed return '0x0'. However, you can just do a check of len of each 's'. :D

if len(s) == 1: s = '0'+s

So, here's the whole code:

def tohex(s):
    hexed = ''
    for x in s:
        a = ord(hex(x)).replace('0x', '')
        if len(a) == 1: a = '0' + a
        a += ' ' #add spaces between hex (looks like an editor)
        hexed += a
    a = a[:-1] # Get rid of the last space
    return hexed

ah len()
I knew I was forgetting something.
thanx :P

I have moved this thread to my forum:
http://tcll5850.proboards.com

please register to view it.
registration does not require personal information :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.