Більшість космічних кодування, які генерують друковані рядки в PHP?

У мене є велика рядок $ string , яка застосовується до md5() , дайте мені

c4ca4238a0b923820dcc509a6f75849b

Довжина 32, я хочу зменшити її, так

base64_encode(md5($string, true));

xMpCOKC5I4INzFCab3WEmw==

Видалення останніх двох == дає мені рядок з довжиною = 22.

Чи є якісь інші кращі алгоритми?

2
Який твій план з остаточною струною? Це для порівняння великих струн? Так що ви просто хочете отримати майже унікальний хеш з цього?
додано Автор Hugo Delsing, джерело
@chao Ти маєш рацію Не зрозумів це.
додано Автор devnull, джерело
Опція - стиснути рядок. Що це ви хочете досягти тут?
додано Автор devnull, джерело
@ Райан, дуже важливо знати, чи ви отримаєте вихідний рядок з вашого "скороченого". Якщо це так, то MD5 - це ніяк.
додано Автор ElmoVanKielmo, джерело
@Gerry, md5 - незворотний алгоритм - цей веб-сайт не "перетворює його назад" - він в основному зберігає хтось вхід "1" з отриманою сумою md5 і відповідає. Проте "1" є лише одним із можливих результатів. Для будь-якої суми md5 існує нескінченна кількість рядків, які скорочуються до цієї одиниці md5.
додано Автор ElmoVanKielmo, джерело
@devnull: стиснення, ймовірно, не допомогло б випадково виглядаючому шістнадцятковому рядку (наприклад, хеш). Інформація, необхідна для розпакування, ймовірно, перевищить збережені байти.
додано Автор cHao, джерело
Як коротко досить короткий?
додано Автор RandomSeed, джерело
Загалом, чим більший алфавіт, до якого ви дозволяєте використовувати меншу кількість символів, необхідних для кодування вашого значення. Тільки ви можете сказати, який розмір алфавіту ви можете використовувати.
додано Автор James K Polk, джерело
Ми дійсно потребуємо більш докладної інформації про те, що саме ви намагаєтесь досягти, щоб забезпечити найкращу відповідь.
додано Автор Nick, джерело
додано Автор Potherca, джерело
Ви можете перетворити його назад на попередню рядок md5 "1". md5.gromweb.com/?md5=c4ca4238a0b923820dcc509a6f75849b . Це зменшилось, П. Або це чи ви могли б дати нам кращу підказку щодо того, що ви намагаєтеся зробити, щоб ми могли надати вам рішення, яке вирішує проблему, що стоїть на початку.
додано Автор Gerry, джерело
@ElmoVanKielmo Я знаю, я вказував, що нам потрібно більше інформації про те, що він насправді намагається вирішити.
додано Автор Gerry, джерело

8 Відповіді

Я не знаю, що ви зрозуміли, що md5 є хеш-функцією, а тому незворотною. Якщо ви не хвилюєтеся про оборотність, то ви можете просто нахилити хеш md5 (або будь-який хеш від вашої симпатії *) до довільної кількості символів. Все це було б збільшити ймовірність зіткнення (я відчуваю , однак це не дає рівномірного поширення).

Якщо ви шукаєте зворотний (тобто неруйнівний) компресію, то не переробляйте колесо. Використовуйте вбудовані функції, такі як gzdeflate() або gzcompress() або інші аналогічні функції .


*Here is a list of hash functions (wikipedia) along with the size of their output. I suppose the smallest possible "hash function" would be a parity bit :)

3
додано

The smaller the length of the string you want .. the smaller the number of possible combination

Загальна кількість можливостей з репутацією

Загальна можливість = n r

Оскільки ми маємо справу з base64 має друковану продукцію, це означає, що ми маємо всього 64 символи

 n = 64 

Якщо ви дивитеся на 22 літери у довжину

n r = 64 22 = 5,444,517,870,735,015,415,413,993,718,908,291,383,296 opportunities

Back to your question : Are there any better algorithm?

Скопіюйте рядок з гарним хешем до бажаної довжини, яку ви хочете, оскільки загальна можливість і зіткнення фіксуються

$string = "the fox jumps over the lazy brown dog";
echo truncateHash($string, 8);

Вихідні дані

9TWbFjOl

Функція використовується

function truncateHash($str, $length) {
    $hash = hash("sha256", $str, true);
    return substr(base64_encode($hash), 0, $length);
} 
2
додано

Одним з кращих способів було б, а не перетворення у бінарну шістнадцяткову (як це робить md5), а потім перетворити рядок на base64, замість того перетворюючи його з шістнадцяткового md5 безпосередньо в base64.

Оскільки шістнадцяткова цифра становить 16 біт на символ, а base64 64 біти на символ, кожен два шестнадцяткові символи складатимуть один символ base64.

Для виконання перетворення ви можете виконати наступне:

  • Split the string into sixteen 2 character chunks
  • The first character should be multiplied by 2 and added to the second (keeping in mind that A-F = 10-15).
  • This number can be matched to the base64 scheme using the table from here: https://en.wikipedia.org/wiki/Base64

Це призведе до строки 16-ти символів base64 з тим самим значенням, що і шістнадцяткове подання рядка md5.

Теоретично, ви можете зробити те ж саме для будь-якої бази. Якщо б ми мали змогу кодувати рядки base128 в ASCII, ми можемо закінчити 8-символьну рядок. Однак, оскільки набір символів обмежений, я думаю, що base64 є найвищою базою, яка зазвичай використовується.

2
додано
Простіший спосіб: перенести true як другий аргумент до md5() , щоб отримати його для повернення сировини.
додано Автор duskwuff, джерело

Не впевнений, що MD5 є правильним вибором для вас, але я вважаю, що у вас є підстави дотримуватися цього алгоритму і шукаєте коротше подання. Існує кілька можливостей для створення коротшого рядка з різними алфавітами:

Варіант 1: Двійковий рядок

Найкоротший формат MD5 - це бінарне подання, щоб отримати такий рядок, який можна просто викликати:

$binaryMd5 = md5($input, true);

Цей рядок, який ви можете зберігати як будь-який інший рядок у базі даних, потрібно лише 16 символів. Просто переконайтеся, що ви правильно втекли, використовуючи mysqli_real_escape_string() або параметризовані запити (PDO).

Варіант 2: кодування Base64

Кодування Base64 вироблятиме рядок з таким алфавітом: [0-9 A-Z a-z + /] і використовує '=' як пробій. Це кодування дуже швидко, але включає іноді небажані символи '+/='.

$base64Md5 = base64_encode(md5($input, true));

Довжина виводу буде дорівнювати 24 символам для хешу MD5.

Варіант 3: кодування Base62

Кодування base62 використовує лише алфавіт [0-9 A-Z a-z]. Такі рядки можна безпечно використовувати для будь-яких цілей, наприклад, токенів у URL-адресі, і вони дуже компактні. Я написав база62 кодер , який може перетворювати двійкові рядки на алфавіт base62 . Це може бути не найшвидшим можливим реалізацією, але я мав на меті написання зрозумілого коду. Цей же клас може бути легко адаптований до різних алфавітів.

$base62Md5 = StoBase62Encoder::base62encode(md5($input, true));

Довжина виводу для хешу MD5 варіюється від 16 до 22 символів.

1
додано

Це кодування генерує коротший рядок,

print base64_encode(hash("crc32b",$string,1));

вихід

qfQIdw==
0
додано
так, у нас кожні ± 2 ^ 32 струни зіткнення? Мені подобається груба сила ...
додано Автор bwoebi, джерело
@bwoebi це залежить від OP, де він хоче використовувати такий хеш, але, здається, довжина хешу критична у цьому конкретному випадку. Що стосується проблем безпеки, є sha256 і sha512 , які є замінами слабкого md5
додано Автор Сухой27, джерело
@duskwuff md5 також є незворотнім перетворенням, вони є обома алгоритмами хешування
додано Автор Сухой27, джерело
CRC32 - це необоротне перетворення. Можливо, ви просто обрізаєте хеш.
додано Автор duskwuff, джерело

Я читаю з вашого повідомлення, що ви шукаєте алгоритм хешування, а не стиснення.

Тут є різні стандартні алгоритми хешування. Погляньте на PHP функції хешування . Залежно від того, що ви хочете хеш, існують різні підходи. Будьте обережні і обчислити середню вірогідність зіткнення.

Однак, здається, ви шукаєте "стиснення", яке виводить мінімально можливий розмір символів для заданої рядки. Якщо так, то подивіться на Лемпель-Зів- Welch ( реалізація PHP ) або інші .

0
додано

Base 91 looks like the most space efficient binary to ASCII printable encoding algorithm (which is what it seems you want).

Я не бачив реалізації PHP, але якщо ваше програмне забезпечення має працювати з іншими, я б дотримуватися Base 64; це добре відомо, блискавка швидко, і доступна скрізь.

0
додано

По-перше, щоб відповісти на ваше запитання: так, є кращий алгоритм (якщо з "краще" ви маєте на увазі "коротший").

Використовуйте функцію hash() (яка має був частиною ядра PHP і включений за замовчуванням з PHP 5.1.2.) з будь-яким з adler32 , fnv132 , crc32 , алгоритми crc32b , fnv132 або joaat .

Без більш глибоких знань про вашу поточну ситуацію, ви також можете вибрати будь-який, який ви думаєте, звучить найхолоднішим.

Ось приклад:

hash('crc32b', $string)

Я встановлюю онлайн-приклад , з якими можна грати.

По-друге, я хотів би зазначити, що те, що ви задаєте, - це майже точний копія іншого запитання тут про stackoverflow

0
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php