Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Системы счисления. Кодировка и обратно. Php и Js (https://javascript.ru/forum/events/37492-sistemy-schisleniya-kodirovka-i-obratno-php-i-js.html)

Mukhtar 22.04.2013 20:38

Цитата:

Сообщение от RazZzeR (Сообщение 247479)
Доброго времени суток, и заранее благодарю. :thanks:
Для понимания должно быть просто.

Название пользовательских файлов = id из базы данных + расширение.
Например "123345666677777888.jpg", "887766252523.png"
Хотел бы чуть уменьшить размер названия файла (особенно некрасиво получается когда id уходит за 9, 12 чисел, слишком длинный адрес)


И, думаю, самым ОПТИМАЛЬНЫМ решением является называть файлы в другой системе счисления. (да еще не надо лишнюю информацию о адресе файла хранить в базе при таком раскладе)

Например: "15099" (10) => "bnf" (36) (в итоге: -2 символа)
И большое число: "1000562" (10) => "lg1e" (36) (в итоге: -3символа)
И еще больше: "1000562627" (10) => "gjpj2b" (36) (в итоге: -4символа)
Напомню, что 36ая система представляет из себя набор всех чисел и букв англ. алфавита (0-9, a-z).

Base = {
 to36 : function (a){ // кодируем
  return this.convert(a, 10, 36);
 },
 to10 : function (a){ // обратно
  return this.convert(a, 36, 10);
 },
 convert : function (number, from, to) {
  return parseInt(number + '', from | 0).toString(to | 0);
 }
}

Вот так реализовано на js, вызывать Base.to36(магические_цифры)

на php вот так:
$binary = '1000562627';
echo base_convert($binary, 10, 36);
(третий пример, выведет "gjpj2b")

Цель: нужны функции кодирования (в новую систему счисления и желательно обратно).
Система счисления: цифры (0-9) и англ. алфавит на обоих раскладках (a-z, A-Z).


И забыл уведомить - Base.convert(a, 10, Любое число больше 36);
вызовет ошибку (что не удивительно):
RangeError: toString() radix argument must be between 2 and 36

Возможны ошибки в построении темы (исправлю) - не сплю 2 дня (посплю в аду, которого нет :D).

Уверен, что есть подобная реализация (если я буду строить такую функцию, то она уйдет у меня более чем в 50 строк, а это неуместно). В любом случае буду благодарен.

Можно на php использовать time();
Например
$ext = preg_replace('/(?:.*)(\.{1}[a-zA-Z]{3,4})$/','$1', $_FILES['fileupload']['name']);
	$unic_name  = time().'_'.rand(0,1000).$ext;

Тогда названия файлов не будут повторяться, и выводиться так 35465468_789.jpg

RazZzeR 23.04.2013 05:17

Цитата:

Сообщение от with-love-from-siberia (Сообщение 247658)
Base64.

Только зачем? 36-ричной системы достаточно. Плюсом является полная реализация как на php, так и на js.

Base64 только усугубит.
36-ричной системы действительно достаточно, НО :)
есть же возможность сделать еще лучше.
Ну да ладно. мне уже ответили, спасибо

RazZzeR 23.04.2013 05:20

Цитата:

Сообщение от Mukhtar (Сообщение 247659)
Можно на php использовать time();
Например
$ext = preg_replace('/(?:.*)(\.{1}[a-zA-Z]{3,4})$/','$1', $_FILES['fileupload']['name']);
	$unic_name  = time().'_'.rand(0,1000).$ext;

Тогда названия файлов не будут повторяться, и выводиться так 35465468_789.jpg

если ставить id в название то 100% повторов не будет, не обязательно так извращаться + не надо хранить название файла, а это экономия :)

Целью моего обращение являлось именно системы счисления.

RazZzeR 23.04.2013 05:21

Цитата:

Сообщение от rgl (Сообщение 247653)
В шестом IE скобочки [] со строкой могут не работать, но можно заменить на charAt()

спрашивая "противопоказания" имел ввиду что-то подобное.

:thanks: благодарен за быстрый ответ и рабочие функции

with-love-from-siberia 23.04.2013 09:34

Цитата:

Сообщение от RazZzeR (Сообщение 247697)
36-ричной системы действительно достаточно, НО :)
есть же возможность сделать еще лучше.

Понимаю, что Вы уже удовлетворены предыдущими ответами. Тем не менее добавлю еще свои пять копеек. 36-ричной системы действительно достаточно.

Отказавшись от основания 36 в пользу более высокого основания (62 или 64) Вы не сделаете лучше. Ощутимой экономии Вы не получите, но добавите необходимость в дополнительной поддержке четырех нестандартных функций (по две в php и js - конвертация числа в строку и обратно).

Оценить разрядности числа в той или иной системе счисления можно по такой формуле
Math.ceil(Math.log(n) / Math.log(base))
. Здесь, n - число, base - основание системы счисления.

Вот грубые оценки. Для представления числа 1e6 необходимо по 4 позиции во всех системах по основаниям 36, 62 и 64. И только для 1e9 в системе по основанию 64 требуется 5 позиций, в то время как в системах по основанию 36 и 62 - по прежнему 6. Более точные оценки Вы можете проделать сами. У Вас действительно так много идентификаторов - больше 1 миллиона, что встала необходимость в незначительном укорочении идентификатора такой большой ценой?

Вот минимальный алгоритм конвертации в любую систему счисления по основанию не выше 64 без проверок корректности входных данных.
var ciphers = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_';

function radixConv(n, base)
{
	var result = [];
	while ( n ) {
		var r = ciphers.charAt(n % base);
		result.push(r);
		n = Math.floor(n / base);
	}
	return result.reverse().join('');
};


// Проверка реализации
var n = 1e6;
alert([
    n, 
    n.toString(10), radixConv(n, 10), 
    n.toString(16), radixConv(n, 16), 
    n.toString(36), radixConv(n, 36), 
].join('\n'));

// Иллюстрация для 1e6
var n = 1e6;
alert([
    n, 
    radixConv(n, 36), 
    radixConv(n, 62), 
    radixConv(n, 64), 
].join('\n'));

// Иллюстрация для 1e9
var n = 1e9;
alert([
    n, 
    radixConv(n, 36), 
    radixConv(n, 62), 
    radixConv(n, 64), 
].join('\n'));

RazZzeR 23.04.2013 16:15

Цитата:

Сообщение от with-love-from-siberia (Сообщение 247707)
Понимаю, что Вы уже удовлетворены предыдущими ответами. Тем не менее добавлю еще свои пять копеек. 36-ричной системы действительно достаточно.

Отказавшись от основания 36 в пользу более высокого основания (62 или 64) Вы не сделаете лучше. Ощутимой экономии Вы не получите, но добавите необходимость в дополнительной поддержке четырех нестандартных функций (по две в php и js - конвертация числа в строку и обратно).

Оценить разрядности числа в той или иной системе счисления можно по такой формуле
Math.ceil(Math.log(n) / Math.log(base))
. Здесь, n - число, base - основание системы счисления.

Вот грубые оценки. Для представления числа 1e6 необходимо по 4 позиции во всех системах по основаниям 36, 62 и 64. И только для 1e9 в системе по основанию 64 требуется 5 позиций, в то время как в системах по основанию 36 и 62 - по прежнему 6. Более точные оценки Вы можете проделать сами. У Вас действительно так много идентификаторов - больше 1 миллиона, что встала необходимость в незначительном укорочении идентификатора такой большой ценой?

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

Вот теперь я понял тебя, большое спасибо за развернутый ответ, отличную рекомендацию. :thanks:
напомню, что я порой часто заказываю скрипты у активных пользователей форума,
могу ли я обращаться к вам, rgl и with-love-from-siberia?

rgl 23.04.2013 20:16

Маленькое предупреждение - при количестве десятичных цифр больше 15 уже не будет хватать точности представления чисел, поэтому правильно работать не будет.

nerv_ 23.04.2013 22:43

Цитата:

Сообщение от danik.js
А смысл?

я тоже не оценил

Цитата:

Сообщение от RazZzeR
если ставить id в название то 100% повторов не будет

sql auto-increment чем не угодил?

RazZzeR 24.04.2013 12:51

Цитата:

Сообщение от nerv_ (Сообщение 247814)
sql auto-increment чем не угодил?

угодил, угодил :)

RazZzeR 24.04.2013 13:01

Цитата:

Сообщение от rgl (Сообщение 247791)
Маленькое предупреждение - при количестве десятичных цифр больше 15 уже не будет хватать точности представления чисел, поэтому правильно работать не будет.

спасибо.

100.000.000.000.000

100 тысяч миллиардов (не знаю как называется).... миллиард картинок представить трудно, думаю до сотни тысяч то не доживу


Часовой пояс GMT +3, время: 02:20.