Зашифруйте целое число, чтобы получить только числовые символы в JAVA

У меня есть идентификатор базы данных, начинающийся с 1 до ..., и мне нужно зашифровать этот номер, чтобы использовать его в качестве номера поиска.
как сгенерировать числовую строку, зашифровав идентификатор базы данных и расшифровав его?
номер поиска должен быть как можно короче.


person Sajad Bahmani    schedule 23.09.2011    source источник
comment
Давайте посмотрим, понял ли я вас... вы хотите сгенерировать еще один Int (зашифрованный) из Int и иметь возможность расшифровать его обратно?   -  person everton    schedule 23.09.2011
comment
Я не буду отмечать это как обман, но это похоже на: Скрыть/зашифровать номер заказа как другой номер: симметричный, «случайный» внешний вид?   -  person Sean Patrick Floyd    schedule 23.09.2011


Ответы (3)


Насколько безопасным должно быть это шифрование? Простой XOR с другим целым может быть тем, что вам нужно, хотя вам, возможно, придется быть осторожным со знаковыми битами.

В качестве альтернативы, если вы хотите что-то более безопасное, просто реализуйте простой 32-битный шифр Фейстеля. Вот один, который я подготовил ранее:

/**
 * IntegerPerm is a reversible keyed permutation of the integers.
 * This class is not cryptographically secure as the F function
 * is too simple and there are not enough rounds.
 *
 * @author Martin Ross
 */
public final class IntegerPerm {

    //////////////////
    // Private Data //
    //////////////////

    /** Non-zero default key, from www.random.org */
    private final static int DEFAULT_KEY = 0x6CFB18E2;

    private final static int LOW_16_MASK = 0xFFFF;
    private final static int HALF_SHIFT = 16;
    private final static int NUM_ROUNDS = 4;

    /** Permutation key */
    private int mKey;

    /** Round key schedule */
    private int[] mRoundKeys = new int[NUM_ROUNDS];

    //////////////////
    // Constructors //
    //////////////////
    public IntegerPerm() { this(DEFAULT_KEY); }

    public IntegerPerm(int key) { setKey(key); }

    ////////////////////
    // Public Methods //
    ////////////////////
    /** Sets a new value for the key and key schedule. */
    public void setKey(int newKey) {
        assert (NUM_ROUNDS == 4) : "NUM_ROUNDS is not 4";
        mKey = newKey;

        mRoundKeys[0] = mKey & LOW_16_MASK;
        mRoundKeys[1] = ~(mKey & LOW_16_MASK);
        mRoundKeys[2] = mKey >>> HALF_SHIFT;
        mRoundKeys[3] = ~(mKey >>> HALF_SHIFT);
    } // end setKey()

    /** Returns the current value of the key. */
    public int getKey() { return mKey; }

    /**
     * Calculates the enciphered (i.e. permuted) value of the given integer
     * under the current key.
     *
     * @param plain the integer to encipher.
     *
     * @return the enciphered (permuted) value.
     */
    public int encipher(int plain) {
        // 1 Split into two halves.
        int rhs = plain & LOW_16_MASK;
        int lhs = plain >>> HALF_SHIFT;

        // 2 Do NUM_ROUNDS simple Feistel rounds.
        for (int i = 0; i < NUM_ROUNDS; ++i) {
            if (i > 0) {
                // Swap lhs <-> rhs
                final int temp = lhs;
                lhs = rhs;
                rhs = temp;
            } // end if
            // Apply Feistel round function F().
            rhs ^= F(lhs, i);
        } // end for

        // 3 Recombine the two halves and return.
        return (lhs << HALF_SHIFT) + (rhs & LOW_16_MASK);
    } // end encipher()


    /**
     * Calculates the deciphered (i.e. inverse permuted) value of the given
     * integer under the current key.
     *
     * @param cypher the integer to decipher.
     *
     * @return the deciphered (inverse permuted) value.
     */
    public int decipher(int cypher) {
        // 1 Split into two halves.
        int rhs = cypher & LOW_16_MASK;
        int lhs = cypher >>> HALF_SHIFT;

        // 2 Do NUM_ROUNDS simple Feistel rounds.
        for (int i = 0; i < NUM_ROUNDS; ++i) {
            if (i > 0) {
                // Swap lhs <-> rhs
                final int temp = lhs;
                lhs = rhs;
                rhs = temp;
            } // end if
            // Apply Feistel round function F().
            rhs ^= F(lhs, NUM_ROUNDS - 1 - i);
        } // end for

        // 4 Recombine the two halves and return.
        return (lhs << HALF_SHIFT) + (rhs & LOW_16_MASK);
    } // end decipher()

    /////////////////////
    // Private Methods //
    /////////////////////

    // The F function for the Feistel rounds.
    private int F(int num, int round) {
        // XOR with round key.
        num ^= mRoundKeys[round];
        // Square, then XOR the high and low parts.
        num *= num;
        return (num >>> HALF_SHIFT) ^ (num & LOW_16_MASK);
    } // end F()

} // end class IntegerPerm
person rossum    schedule 23.09.2011
comment
круто спасибо большое. Очень удобно для шифрования на месте в таблице, хранящей целые числа. Разместите версию своего кода на Python по адресу gist.github.com/1404682. - person Nicolas78; 29.11.2011
comment
что, если мне нужно только положительное число для зашифрованного значения? - person Prashant; 03.07.2019
comment
Если возвращаемое число отрицательное, просто добавьте 2^32 для 32-битных целых чисел (или 2^64 для 64-битных целых чисел). Вам нужно будет увеличить размер на один размер, чтобы результат соответствовал результату без переполнения. - person rossum; 03.07.2019

как насчет преобразования Integer (DEC) -> Octal?

ну, 1-7 не будут «зашифрованы» таким образом.

person Kent    schedule 23.09.2011
comment
Это не совсем шифрование. - person everton; 23.09.2011
comment
Вы можете просто использовать одно и то же значение. Либо значение +1. Шифрование работает только с приватным ключом, иначе вы теряете возможность расшифровки (путем генерации хеша, например) - person michael667; 23.09.2011
comment
ну, я думаю, что это своего рода шифрование, но алгоритм прост, как десятично-восьмеричный. даже исходное целое + магическое число также можно назвать шифрованием. Это зависит от того, насколько безопасна зашифрованная строка/целое число OP. Я думаю, он просто не хочет, чтобы пользователь знал настоящий идентификатор. - person Kent; 23.09.2011
comment
Верно, но какие преимущества (безопасности) вы получаете от такого шифрования? - person michael667; 23.09.2011
comment
@ michael667 michael667, как я уже сказал, это зависит от требований безопасности его приложения. Если ему нужен действительно безопасный алгоритм, мой неприемлем. - person Kent; 23.09.2011

Вы можете получить хороший криптографически безопасный генератор случайных чисел, добавить в базу данных таблицу, которая связывает идентификаторы с их зашифрованными версиями, и все готово.

Просто создайте случайное число для каждого идентификатора, убедитесь, что он еще не используется в качестве зашифрованной версии какого-либо другого идентификатора, и вуаля.

Это помешает любому, кто попытается взломать схему, которую вы используете, поскольку вы фактически ее не используете.

person Olathe    schedule 28.09.2012