文本字符串到唯一整数方法?

时间:2015-07-29 13:33:52

标签: python python-3.x

是否有将'you'等文本字符串转换为

以外的数字的方法
y = tuple('you')
for k in y:
  k = ord(k)

一次只转换一个字符?

5 个答案:

答案 0 :(得分:8)

为了将字符串转换为数字(反之),您应该首先使用bytes。由于您使用的是Python 3,因此字符串实际上是Unicode字符串,因此可能包含ord()值高于255的字符。bytes但每个字符只有一个字节;所以你应该先在这两种类型之间进行转换。

基本上,您正在寻找一种方法将bytes字符串(基本上是字节列表,数字列表0-255)转换为单个数字,反之亦然。您可以使用int.to_bytesint.from_bytes

import math
def convertToNumber (s):
    return int.from_bytes(s.encode(), 'little')

def convertFromNumber (n):
    return n.to_bytes(math.ceil(n.bit_length() / 8), 'little').decode()
>>> convertToNumber('foo bar baz')
147948829660780569073512294
>>> x = _
>>> convertFromNumber(x)
'foo bar baz'

答案 1 :(得分:1)

  1. 您不需要将字符串转换为元组
  2. >>> text = 'you' >>> [ord(ch) for ch in text] [121, 111, 117] 被覆盖。使用列表理解:
  3. 之类的东西收集项目
    >>> numbers = [ord(ch) for ch in text]
    >>> ''.join(chr(n) for n in numbers)
    'you'
    

    要取回文字,请使用chr,然后使用str.join加入字符:

    JFileChooser chooser= new JFileChooser();
    chooser.showOpenDialog(chooser);
    File file = chooser.getSelectedFile();
    String Content = "What you want to append to file";
    
    try 
    {
        RandomAccessFile random = new RandomAccessFile(file, "rw");
        long length = random.length();
        random.setLength(length + 1);
        random.seek(random.length());
        random.writeBytes(Content);
        random.close();
    } 
    catch (Exception exception) {
        //exception handling
    }
    

答案 2 :(得分:0)

将字符串视为基数为255的数字。

# Reverse the digits to make reconstructing the string more efficient
digits = reversed(ord(b) for b in y.encode())
n = reduce(lambda x, y: x*255 + y, digits)

new_y = ""
while n > 0:
    n, b = divmod(n, 255)
    new_y += chr(b)
assert y == new_y.decode()

(请注意,这与poke的答案基本相同,但显式编写而不是使用可用的方法在字节字符串和整数之间进行转换。)

答案 3 :(得分:0)

我试图找到一种方法将一个 numpy 字符数组转换为一个唯一的数字数组,以便做一些其他的事情。我已经实现了以下功能,包括@poke 和@falsetrue 的答案(当字符串太大时,这些方法给我带来了一些麻烦)。我还添加了哈希方法(哈希是一个固定大小的整数,用于标识特定值。)

import numpy as np
def str_to_num(x):
    """Converts a string into a unique concatenated UNICODE representation

    Args:
        x (string): input string

    Raises:
        ValueError: x must be a string

    """
    if isinstance(x, str):
        x = [str(ord(c)) for c in x]
        x = int(''.join(x))
    else:
        raise ValueError('x must be a string.')

    return x


def chr_to_num(x):
    return int.from_bytes(x.encode(), 'little')


def char_arr_to_num(arr, type = 'hash'):
    """Converts a character array into a unique hash representation.

    Args:
        arr (np.array): numpy character array.
    """
    if type == 'unicode':
        vec_fun = np.vectorize(str_to_num)
    elif type == 'byte':
        vec_fun = np.vectorize(chr_to_num)
    elif type == 'hash':
        vec_fun = np.vectorize(hash)    
    out = np.apply_along_axis(vec_fun, 0, arr)
    out = out.astype(float)
    return out

a = np.array([['x', 'y', 'w'], ['x', 'z','p'], ['y', 'z', 'w'], ['x', 'w','y'], ['w', 'z', 'q']])
char_arr_to_num(a, type = 'unicode')
char_arr_to_num(a, type = 'byte')
char_arr_to_num(a, type = 'hash')

答案 4 :(得分:0)

虽然有很多方法可以完成这个任务,但我更喜欢散列方法,因为它有以下很好的特性

  1. 它确保您得到的数字是高度随机的,实际上是均匀随机的
  2. 它确保即使输入字符串的微小变化也会导致输出整数的显着差异。
  3. 这是一个不可逆的过程,也就是说,您无法根据整数输出判断哪个字符串是输入。

    import hashlib
    # there are a number of hashing functions you can pick, and they provide tags of different lengths and security levels.
    hashing_func = hashlib.md5
    
    # the lambda func does three things
    # 1. hash a given string using the given algorithm
    # 2. retrive its hex hash tag
    # 3. convert hex to integer 
    str2int = lambda s : int(hashing_func(s.encode()).hexdigest(), 16) 

要查看生成的整数如何均匀随机分布,我们首先需要一些随机字符串生成器


    import string
    import numpy as np 
    # candidate characters
    letters = string.ascii_letters
    # total number of candidates
    L = len(letters)
    # control the seed or prng for reproducible results
    prng = np.random.RandomState(1234)
    
    # define the string prng of length 10
    prng_string = lambda : "".join([letters[k] for k in prng.randint(0, L, size=(10))])

现在我们生成足够数量的随机字符串并得到相应的整数


    ss = [prng_string() for x in range(50000)]
    vv = np.array([str2int(s) for s in ss])

让我们通过比较均匀分布的理论均值和标准差与我们观察到的值来检查随机性。


    for max_num in [256, 512, 1024, 4096] :
        ints = vv % max_num
        print("distribution comparsions for max_num = {:4d} \n\t[theoretical] {:7.2f} +/- {:8.3f} | [observed] {:7.2f} +/- {:8.3f}".format(
            max_num, max_num/2., np.sqrt(max_num**2/12), np.mean(ints), np.std(ints)))

最后你会看到下面的结果,说明你得到的数字很统一。

distribution comparsions for max_num =  256 
    [theoretical]  128.00 +/-   73.901 | [observed]  127.21 +/-   73.755
distribution comparsions for max_num =  512 
    [theoretical]  256.00 +/-  147.802 | [observed]  254.90 +/-  147.557
distribution comparsions for max_num = 1024 
    [theoretical]  512.00 +/-  295.603 | [observed]  512.02 +/-  296.519
distribution comparsions for max_num = 4096 
    [theoretical] 2048.00 +/- 1182.413 | [observed] 2048.67 +/- 1181.422

值得指出的是,其他发布的答案可能无法达到这些属性。

例如,@poke 的 convertToNumber 解决方案将给出

distribution comparsions for max_num =  256 
    [theoretical]  128.00 +/-   73.901 | [observed]   93.48 +/-   17.663
distribution comparsions for max_num =  512 
    [theoretical]  256.00 +/-  147.802 | [observed]  220.71 +/-  129.261
distribution comparsions for max_num = 1024 
    [theoretical]  512.00 +/-  295.603 | [observed]  477.67 +/-  277.651
distribution comparsions for max_num = 4096 
    [theoretical] 2048.00 +/- 1182.413 | [observed] 1816.51 +/- 1059.643