используют комбинацию mktime
и date
:
$date_half_a_year_ago = mktime(0, 0, 0, date('n')-6, 1, date('y'))
, чтобы сделать новую дату относительно данной даты, а не сегодня, вызовите date
со вторым параметром
$given_timestamp = getSomeDate();
$date_half_a_year_ago = mktime(0, 0, 0, date('n', $given_timestamp)-6, 1, date('y', $given_timestamp))
, чтобы вывести его в формате, просто снова используйте date
:
echo date('F j, Y', $date_half_a_year_ago);
Это действительно зависит от природы двоичных данных и ограничений, которые "текст" накладывает на ваш вывод.
Во-первых, если ваши двоичные данные не сжаты, попробуйте сжать перед кодирование. Тогда мы можем предположить, что распределение 1/0 или отдельных байтов является более или менее случайным.
Теперь: зачем вам текст? Обычно это происходит потому, что канал связи не проходит через всех персонажей одинаково. например, вам может потребоваться чистый текст ASCII, чьи печатаемые символы находятся в диапазоне от 0x20-0x7E. Вам предстоит играть с 95 персонажами. Каждый символ теоретически может кодировать log2 (95) ~ = 6,57 бит на символ. Легко определить преобразование, которое подходит довольно близко.
Но: что, если вам нужен символ-разделитель? Теперь у вас всего 94 символа и т. Д. Так что выбор кодировки действительно зависит от ваших требований.
Возьмем чрезвычайно глупый пример: если ваш канал передает все 256 символов без проблем и вам не нужны никакие разделители, тогда вы можете написать тривиальное преобразование, которое достигнет 100% эффективность. :-) Как это сделать, оставлено в качестве упражнения для читателя.
UTF-8 не является хорошим транспортом для произвольно закодированных двоичных данных. Он может передавать значения 0x01-0x7F с накладными расходами всего 14%. Я не уверен, что 0x00 допустимо; скорее всего нет. Но все, что выше 0x80, расширяется до нескольких байтов в UTF-8. Я бы рассматривал UTF-8 как ограниченный канал, который передает 0x01-0x7F или 126 уникальных символов. Если вам не нужны разделители, вы можете передавать 6,98 бит на символ.
Общее решение этой проблемы: Предположим, что алфавит состоит из N символов, двоичная кодировка которых от 0 до N-1. (Если кодировки не такие, как предполагалось, используйте таблицу поиска для перевода между нашим промежуточным представлением 0..N-1 и тем, что вы фактически отправляете и получаете.)
Предположим, что в алфавите 95 символов. Теперь: некоторые из этих символов будут представлять 6 бит, а некоторые - 7 бит. Если у нас есть 6-битные символы A и 7-битные символы B, то:
A + B = 95 (общее количество символов) 2A + B = 128 (общее количество 7-битных префиксов, которые могут быть созданы. Вы можете начать 2 префикса с 6-битного символа или один с 7-битного символа.)
Решая систему, вы получаете: А = 33, В = 62. Теперь вы составите таблицу символов:
Raw Encoded 000000 0000000 000001 0000001 ... 100000 0100000 1000010 0100001 1000011 0100010 ... 1111110 1011101 1111111 1011110
Для кодирования сначала сдвиньте 6 битов ввода. Если эти шесть битов больше или равны 100001, сдвиньте другой бит. Затем найдите соответствующий 7-битный выходной код, преобразуйте, чтобы он поместился в выходном пространстве, и отправьте. Вы будете сдвигать 6 или 7 битов ввода на каждой итерации.
Чтобы декодировать, примите байт и преобразуйте его в исходный код вывода. Если исходный код меньше 0100001, перенесите соответствующие 6 бит на свой вывод. В противном случае перенесите соответствующие 7 бит на ваш вывод. Вы будете генерировать 6-7 битов вывода на каждой итерации.
Я думаю, что для равномерно распределенных данных это оптимально. Если вы знаете, что у вас в исходном коде больше нулей, чем единиц, тогда вы можете сопоставить 7-битные коды с началом пространства, чтобы с большей вероятностью вы могли использовать 7-битный код.
Похоже, у тебя уже есть ответ, Марк. UTF-8 бесполезен в качестве двоичной кодировки, поскольку любой символ UTF-8 размером более одного байта имеет более 25% служебных данных даже для хранения текста (2 или более бит на байт). Кодировки Base64 уже лучше.