Показать сообщение отдельно
  #15 (permalink)  
Старый 23.04.2013, 09:34
Профессор
Отправить личное сообщение для with-love-from-siberia Посмотреть профиль Найти все сообщения от with-love-from-siberia
 
Регистрация: 14.12.2009
Сообщений: 155

Сообщение от RazZzeR Посмотреть сообщение
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'));
Ответить с цитированием