Here is my solution now, using only one dict.
class StringTable(object):
    def __init__(self):
        self.table = {}
    def probe_id(self, ss):
        table = self.table
        id_ = hash(ss)
        while True:
            s = table.get(id_, None)
            # id_ not use, return it
            if s is None:
                return id_, False
            # id_ used and equal to ss
            if ss == s:
                return id_, True
            # id_ used by other string, probe again!
            id_ = id_ + 1
            # don't use this, endless loop, why?
            #id_ = hash(id_)
    def store(self, ss):
        id_, occupied = self.probe_id(ss)
        if not occupied:
            self.table[id_] = ss
            print 'store {%s: %r}' % (id_, ss)
        return id_
    def get_string_from_id(self, id_):
        ret = self.table.get(id_, None)
        print 'get_string_from_id %s -> %r' % (id_, ret)
        return ret
    def get_id_from_string(self, ss):
        id_, occupied = self.probe_id(ss)
        ret = id_ if occupied else None
        print 'get_id_from_string %r -> %s' % (ss, ret)
        return ret
st = StringTable()
# http://bugs.python.org/issue14621
s1 = "\x00\xcf\x0b\x96\x19"
s2 = "\x00\x6d\x29\x45\x18"
print repr(s1), hash(s1)
print repr(s2), hash(s2)
id1 = st.store(s1)
id2 = st.store(s2)
st.get_string_from_id(id1)
st.get_string_from_id(id2)
st.get_id_from_string(s1)
st.get_id_from_string(s2)
Output:
jayven@laptop:~/test$ python stringtable.py
'\x00\xcf\x0b\x96\x19' 1220138288
'\x00m)E\x18' 1220138288
store {1220138288: '\x00\xcf\x0b\x96\x19'}
store {1220138289: '\x00m)E\x18'}
get_string_from_id 1220138288 -> '\x00\xcf\x0b\x96\x19'
get_string_from_id 1220138289 -> '\x00m)E\x18'
get_id_from_string '\x00\xcf\x0b\x96\x19' -> 1220138288
get_id_from_string '\x00m)E\x18' -> 1220138289