крошечное случайно выглядящее идентификационное поколение

Я нашел решение этой проблемы.

Чтобы решить проблему:

1- Нет проблем, когда я использую какие-либо обещания в своем коде. 2. Нет проблем, когда я использую angularfire-lite.

Таким образом, есть 2 решения: 1- Использование angularfire-lite

2- Использование кода node.js для серверной версии приложения. Я имею в виду файл "server.js" или "server.ts".

Я использую JavaScript для моего «серверного» файла. Поэтому я могу добавить код node.js в server.js для обновления тегов og. Для этого первым шагом является создание serve.js. Затем найдите, куда вы хотите добавить мета-теги. А потом развернуть. Вот и все. Результат примерно такой.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.database();
/*<<-Just for ssr*/

var SeoServiceService = /** @class */ (function () {
function SeoServiceService(titleService, meta, router) {
    this.titleService = titleService;
    this.meta = meta;
    this.router = router;
}
SeoServiceService.prototype.generateTags = function (config) {

    console.log('Client Side');
    /*Just for ssr->>*/
    return db.ref('test/ssr').on('value',(snapshot)=>{
        console.log('Server Side');

        this.meta.updateTag({ property: 'og:title', content: 'It works :)' });
        return true
        });
        /*Just for ssr->>*/
    console.log('Client Side');
};
SeoServiceService.ngInjectableDef = i0.defineInjectable({ factory: function SeoServiceService_Factory() { return new SeoServiceService(i0.inject(i1.Title), i0.inject(i1.Meta), i0.inject(i2.Router)); }, token: SeoServiceService, providedIn: "root" });
return SeoServiceService;
}());

«Server.js» - это большой и сложный файл. Трудно найти, где вы должны добавить свой код node.js. Одним из решений является добавление вашего node.js в качестве комментария к угловому коду. После создания 'server.js' просто найдите этот комментарий и сделайте его работоспособным. Например, мой угловой код приведен ниже. И окончательный результат выше кода.

import { Injectable } from '@angular/core';
import { Title, Meta } from '@angular/platform-browser';
import { Router } from '@angular/router';

/*Just for ssr->>*/
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.database();
/*<<-Just for ssr*/

@Injectable({
   providedIn: 'root'
})
export class SeoServiceService {

constructor(
    private titleService: Title,
    private meta: Meta,
    private router: Router,
 ) { }

generateTags(config) {
console.log('Client Side');
/*Just for ssr->>
return db.ref('test/ssr').on('value',(snapshot)=>{
    console.log('Server Side');

    this.meta.updateTag({ property: 'og:title', content: 'It works :)' });
    return true
    });
    Just for ssr->>*/
console.log('Client Side');

}}

6
задан Cœur 23 August 2017 в 06:11
поделиться

3 ответа

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

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

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

В результате вы будете более эффективно использовать адресное пространство своего идентификатора и будете значительно реже увеличивать длину.

Относительно вашего вопроса об ограничении длины MD5, я думаю, что выбор MD5 - это перебор. Вам действительно не нужен криптографический (псевдо) безопасный хеш. Вам нужен генератор случайных битов, для которого вы можете использовать crc32 (или adler, который работает быстрее). Особенно, если код должен быть запущен на мобильном телефоне. Чтобы реализовать генератор случайных битов с помощью crc32, добавьте 32-битное значение к строке для хеширования и инициализируйте ее постоянным значением по вашему выбору (начальное число). Затем вычислите crc32 для этой строки. Если вам нужно больше байтов, запишите полученное значение crc32 в 32 бита перед строкой и пересчитайте crc32. Итерируйте, пока у вас не будет достаточно битов. Вам нужен генератор случайных битов, для которого вы можете использовать crc32 (или adler, который работает быстрее). Особенно, если код должен быть запущен на мобильном телефоне. Чтобы реализовать генератор случайных битов с помощью crc32, добавьте 32-битное значение к строке для хеширования и инициализируйте ее постоянным значением по вашему выбору (начальное число). Затем вычислите crc32 для этой строки. Если вам нужно больше байтов, запишите полученное значение crc32 в 32 бита перед строкой и пересчитайте crc32. Итерируйте, пока у вас не будет достаточно битов. Вам нужен генератор случайных битов, для которого вы можете использовать crc32 (или adler, который работает быстрее). Особенно, если код должен быть запущен на мобильном телефоне. Чтобы реализовать генератор случайных битов с помощью crc32, добавьте 32-битное значение к строке для хеширования и инициализируйте ее постоянным значением по вашему выбору (начальное число). Затем вычислите crc32 для этой строки. Если вам нужно больше байтов, запишите полученное значение crc32 в 32 бита перед строкой и пересчитайте crc32. Итерируйте, пока у вас не будет достаточно битов. запишите полученное значение crc32 в 32 бита перед строкой и пересчитайте crc32. Итерируйте, пока у вас не будет достаточно битов. запишите полученное значение crc32 в 32 бита перед строкой и пересчитайте crc32. Итерируйте, пока у вас не будет достаточно битов. Вы можете заменить crc32 алгоритмом по вашему выбору. Это дает дешевый и быстрый генератор случайных битов, где начальная константа является начальным числом.

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

Что касается кодирования, вы не указали ограничения. Можете ли вы использовать прописные и строчные буквы с цифрами? В вашем примере используется алфавит из 36 различных значений ASCII. Если у вас есть генератор псевдослучайных чисел, описанный выше, который может генерировать столько байтов, сколько необходимо, просто определите длину, чтобы быть числом букв вашего идентификатора, и выберите следующую букву по модулю следующего случайного байта. Тогда вы будете точно знать, сколько байтов генерировать за один раз, и генерация идентификатора тривиальна.

1
ответ дан 17 December 2019 в 07:08
поделиться

How about something like this:

  1. If you want 4 character keys using a-zA-Z0-9, then you'd have: 62^4 = > 14 million possible values.

  2. Break this up into N partitions: 0000 ... 1000, 1001 ... 2000 , ... , ZZAA ... ZZZZ

    Each partition is represented by an entity with: start id end id current id

Now, to generate an ID:

  1. randomly pick a partition. Use the start key for each partition as a key. Начать транзакцию:
  2. get_or_create () этой сущности раздела.
  3. если текущий идентификатор == конечный идентификатор, перейти к шагу 1
  4. сохранить текущий идентификатор
  5. увеличить текущий идентификатор на единицу Завершить транзакцию

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

Если вы выберете N равным 140, у каждого раздела будет 100 000 значений. Это позволило бы довольно много одновременных вставок при ограничении количества повторных попыток из-за выбора «пустого» раздела.

Возможно, вам нужно подумать об этом больше. Особенно, как вы справитесь со случаем, когда вам нужно перейти на 5 или 6-значные клавиши?

-Dave

2
ответ дан 17 December 2019 в 07:08
поделиться

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

Length     Count      MD5             Base 62
4          400        3d0e            446
5          925        4fc04           1Myi
6          2434       0e9368          40V6
7          29155      e406d96         GBFiA
8          130615     7ba787c8        2GOiCm
9          403040     75525d163       YNKjL9
10         1302992    e1b3581f52      H47JAIs
Total:     1869561

Каждый раз, когда длина хеша увеличивалась, это происходило из-за столкновения, поэтому в этом случае было шесть столкновений. Количество - это количество ключей заданной длины, которые были сгенерированы до столкновения. Столбец MD5 показывает последний усеченный ключ, который был успешно добавлен до того, как произошла ошибка дублированного ключа. В крайнем правом столбце показан ключ в базе 62 (если я правильно сделал преобразование).

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

Для всех, кто интересуется, вот как я получил представление base 62 для последнего столбца:

def base_62_encode(input):
    "Inspired by code at http://en.wikipedia.org/wiki/Base_36."
    CLIST="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    rv = ""
    while input != 0:
        rv = CLIST[input % 62] + str(rv)
        input /= 62
    return rv

base62_id = base_62_encode(long(truncated_hash, 16))

(Добавлено позже:)

Вот класс, который заботится о нескольких вещах, связанных с генерацией этих идентификаторов. в контексте Google App Engine. По умолчанию ключи, сгенерированные этим классом, не являются чисто базовыми 62, поскольку первый символ имени ключа GAE должен быть буквенным. Это требование было решено с помощью базы 52 для первого символа.

Первичная база может быть изменена на что-то, отличное от 62, путем изменения значения «clist», которое было передано (или опущено) в конструкторе. Возможно, вы захотите удалить символы, которые легко перепутать, например, «1», «l», «i» и т. Д.

Использование:

keygen = LengthBackoffIdGenerator(SomeClass, initial_length=5)
small_id, modified = keygen.small_id(seed_value_from_sharded_counter)

Вот класс:

class LengthBackoffIdGenerator(object):
    """Class to generate ids along the lines of tinyurl.

    By default, ids begin with a alphabetic character.  Each id that is created is checked against previous ones
    to ensure uniqueness.  When a duplicate is generated, the length of the seed value used is increased by one
    character.

    Ids become gradually longer over time while remaining relatively short, and there are very few retries in 
    relation to the number of keys generated.
    """
    ids = set()

    def __init__(self, cls, clist='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', alpha_first=False,
            initial_length=5, check_db=False):
        self.clist = clist
        self.alpha_first = alpha_first
        if self.alpha_first:
            import re
            alpha_list = re.sub(r'\d', '', clist)
            if len(alpha_list) < 1:
                raise Exception, 'At least one non-numeric character is required.'
            self.alpha_list = alpha_list
        self.cls = cls
        self.length = initial_length
        self.check_db = check_db

    def divide_long_and_convert(self, radix, clist, input, rv):
        "Inspired by code at http://en.wikipedia.org/wiki/Base_36."
        rv += clist[input % radix]
        input /= radix
        return (input, rv)

    def convert_long(self, input):
        rv = ""
        if self.alpha_first:
            input, rv = self.divide_long_and_convert(len(self.alpha_list), self.alpha_list, input, rv)
        while input != 0:
            input, rv = self.divide_long_and_convert(len(self.clist),      self.clist,      input, rv)
        return rv

    def hash_truncate_and_binify(self, input, length):
        """Compute the MD5 hash of an input string, truncate it and convert it to a long.

        input  - A seed value.
        length - The length to truncate the MD5 hash to.
        """
        from assessment.core.functions import md5_hash
        input = md5_hash(input)[0:length]
        return long(input, 16)

    def _small_id(self, input):
        """Create an ID that looks similar to a tinyurl ID.

        The first letter of the ID will be non-numeric by default.
        """
        return self.convert_long(self.hash_truncate_and_binify(input, self.length))

    def small_id(self, seed):
        key_name = self._small_id(seed)
        increased_length = False
        if self.check_db and not self.cls.get_by_key_name(key_name) is None:
            self.ids.add(key_name)
        if key_name in self.ids:
            self.length += 1
            increased_length = True
            key_name = self._small_id(seed)
        self.ids.add(key_name)
        return (key_name, increased_length)
1
ответ дан 17 December 2019 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: