Имя: Пароль:
1C
 
Как перевести ГУИД в число и обратно? Продолжение
,
0 Mr_Best
 
13.02.17
02:42
Доброго времени коллеги !

Необходимо преобразовать ГУИД в число и обратно, нашел эту ветку v8: Как перевести ГУИД в число и обратно?

В самом конце есть две функцию, делающие желанные мной вычисления. Но они не работают из "коробки", так как авто забыл приложить дополнительные нестандартные функции.

А именно:
- бфМат.ПереводЧислаВСистемуСчисления(Ч, 16);
- бфМат.ПереводИзСистемыСчисленияВЧисло(СтрGUID, 16);
- бфСтроки.ДобавитьНачСимвол(СтрокаЧ16, 32, "0");

Первые две я заменил функциями вот отсюда: Книга знаний: Математические вычисления в 1С

Осталась последняя: бфСтроки.ДобавитьНачСимвол(СтрокаЧ16, 32, "0");

Что эта функция должна делать не могу догадаться ! Может кто знает ? Может Гений 1С скинет недостающие ?
1 h-sp
 
13.02.17
02:50
добавляет левые нули похоже
2 Mr_Best
 
13.02.17
02:51
я попробовал добавить с лева ноль, и два нуля, все тщетно
3 Torquader
 
13.02.17
03:09
Что такое ГУИД - это 16 байт.
Как перевести 16 байт в число - очень просто - вывести как десятичное число путём деления на 10 с остатком, рассматривая как очень длинное целое.
В 1С с этим не должно быть проблем, так как для 1С очень длинные целые могут быть и более 16 байт.
4 h-sp
 
13.02.17
03:20
(2) вы добавляйте ноль в короткие строки, если строка уже 32 символа, добавлять ноль не нужно.
5 Рэйв
 
13.02.17
08:28
как вариант:-)

//------
    
    УИД=СтрЗаменить(ВРЕГ(Строка(ссылка.УникальныйИдентификатор())),"-","");
м16=Новый Массив;
мЧ=Новый Массив;
м16.Добавить("0");
м16.Добавить("1");
м16.Добавить("2");
м16.Добавить("3");
м16.Добавить("4");
м16.Добавить("5");
м16.Добавить("6");
м16.Добавить("7");
м16.Добавить("8");
м16.Добавить("9");
м16.Добавить("A");
м16.Добавить("B");
м16.Добавить("C");
м16.Добавить("D");
м16.Добавить("E");
м16.Добавить("F");

мЧ.Добавить("00");
мЧ.Добавить("01");
мЧ.Добавить("020");
мЧ.Добавить("03");
мЧ.Добавить("04");
мЧ.Добавить("05");
мЧ.Добавить("06");
мЧ.Добавить("07");
мЧ.Добавить("08");
мЧ.Добавить("09");
мЧ.Добавить("10");
мЧ.Добавить("11");
мЧ.Добавить("12");
мЧ.Добавить("13");
мЧ.Добавить("14");
мЧ.Добавить("15");


    Результат="";
    Для н=1 по СтрДлина(УИД) Цикл
        Сим=Сред(УИД,н,1);
        
        инд=0;
        НетСовпадений=Истина;
        Для Каждого Зн16 из м16 Цикл
            Если Зн16=Сим Тогда
                Результат=Результат+мЧ[инд];
                НетСовпадений=Ложь;
                Прервать;
            КонецЕсли;
            инд=инд+1;
        КонецЦикла;    
        
        Если НетСовпадений Тогда
            Сообщить("Неопределен символ '"+Сим+"' для преобразование в число.");
            Возврат;
        КонецЕсли;    
    КонецЦикла;
    Сообщить("УИД:'"+УИД +"'
    |Результат:'"+Результат+"'");
6 totparen
 
13.02.17
08:47
С какой целью преобразования?
7 totparen
 
13.02.17
08:52
Писал нечто похоже, переводил внутренний идентификатора из 1C 7.7 в GUID и обратно.
8 Mr_Best
 
13.02.17
09:51
(6) цель простая. У справочника есть реквизит МетаКод, принимающий значение например от 0 до 99. При записи справочника его необхожимо рассчитать по формуле х mod 99, где первые две цифры после нуля будет искомое значение. Таким образом числа 50, 150, 250 и т.д. до хуллиардов будут иметь МетаКод 50, другими словами каждый 50-тый. Используется для многопоточного обменна данными, где 99 количество потоков, а 50 номер потока который отправит эту регистрацию данных.
9 Кирпич
 
13.02.17
09:53
есть такая фигня

&НаКлиенте
Функция ГуидВЧисло(Гуид)
    Гуид = СтрЗаменить(ВРег(Строка(Гуид)),"-","");
    Цифры="0123456789ABCDEF";
    Длина = СтрДлина(Цифры);
    ДлинаСтроки = СтрДлина(Гуид);
    Результат = 0;
    Для А = 1 По ДлинаСтроки Цикл
        Символ = Сред(Гуид, А,1);
        Поз = Найти(Цифры,Символ)-1;
        Результат = Результат * Длина + Поз;
    КонецЦикла;
    Возврат(Результат);
КонецФункции


&НаКлиенте
Процедура Команда1(Команда)
КлючУникальности = Новый УникальныйИдентификатор;
Сообщить(КлючУникальности);
Сообщить(ГуидВЧисло(КлючУникальности));
КонецПроцедуры
10 Волшебник
 
модератор
13.02.17
09:53
(8) Чушь какая-то
11 Cyberhawk
 
13.02.17
09:57
(8) Для многопоточности хранить маркировку объектов в базе не нужно, что-то ты перемудрил. Ну или поясни, зачем хранить маркеры в базе
12 Mr_Best
 
13.02.17
09:59
(8)  кому чушь, кому скорость в на порядок выше пры выгрузки, но мы же 1сники, о какой это скрости я тут задумался ?
13 Mr_Best
 
13.02.17
10:08
(11) транспорт обмена http для общего понимания. При записи справочника создается запись в справонике регистраций, у которого есть числовой код, имя метаданных, ссылка на отправляемый элемент и признак что объект был физически удален. По коду определяется порядок отправки, но при делении на например два потока цепочку изменений одного объекта нужно целиком отнести в один поток, тут мне и поможет метаКод.
14 Cyberhawk
 
13.02.17
10:13
(13) Зачем нужно выгружать цепочку изменений объекта, а не его текущее состояние?
15 Mr_Best
 
13.02.17
10:18
(14) вообще то вы правы, я планировал держать всегда один, но на принимающей стороне тоже этот объект может быть изменен, при разраве связи и отказа онлайн обмена, возможно прийдется решать коллизию, тут это и пригодится.
16 Mr_Best
 
13.02.17
10:20
(14) итоговая система онлайн обмена будет просто содержать настройку, с историей или без
17 EugeniaK
 
13.02.17
10:23
А при чем тут вообще ГУИД?
Присваивай рандомное число от 1 до 50ти.
Выборка ровнее будет.
18 Cyberhawk
 
13.02.17
10:24
(16) Даже если нужно выгружать историю состояний объекта, то не ясно, почему не хватает ссылки на объект БД в твоем отдельном справочнике и зачем маркировать сам объект БД...
19 Mr_Best
 
13.02.17
10:39
(17) вариант ))) раз выгрузка равномернее будет, тогда так и надо сделать.
(16) объект баз данных не маркируется, маркируется его регистрация, по одной лишь ссылке невозможно определить диапазон потоков, нужно преобразовать сначала в число. А если в про то, что по ссылке в момент отправки можно все рассчитать, то тут все просто, упадет производительность. Я добился увеличения скорости обмена по тестам в 10 раз ! И эта цифра ограничена в том числе количеством потоков и может быть быстрее, все зависит от свободных ресурсов. Код должен быть написан так, что бы "вся нагрузка" была полезной, вот и заморачиваюсь с математикой.
20 МихаилМ
 
13.02.17
15:31
максимальный гуид не помещает в тип число 1с.
21 Кирпич
 
13.02.17
15:47
(20) а какое число у 1С максимальное?
22 Mr_Best
 
13.02.17
15:47
(20) я тоже на это подумал, потому что если у гуида убрать "-" и получившееся 16-ти разрядное число конвернуть в 10 и обратно в 16, результат разнится. Остается тогда вопрос, как у Гения 1С это работает по ссылке v8: Как перевести ГУИД в число и обратно?
23 Mr_Best
 
13.02.17
15:48
(21) в реквизитах максиму 32 разряда, в номере 50, где-то видел больше, не помню где ...
24 Кирпич
 
13.02.17
16:03
(20) проверил. всё влазит.
25 Кирпич
 
13.02.17
16:04
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
340 282 366 920 938 463 463 374 607 431 768 211 455
26 Кирпич
 
13.02.17
16:06
проверял здесь
http://web2.0calc.com/#collapse_largenumber
27 Кирпич
 
13.02.17
16:13
Нафига это надо (0) даже вникать не хочу. Чую, глупость какая то.
28 Mr_Best
 
13.02.17
16:13
(26) так получилось 39 разрядов, быстрый поиск по гуглу сказал, что максимум 38 разрядов
29 Кирпич
 
13.02.17
16:15
(28) в (25) написала 1С. я ж не сам придумал
30 Mr_Best
 
13.02.17
16:16
(17) вообще не будем мчать 1с, сделаю как (17), просто и эффективно, а самое главное быстро
31 Кирпич
 
13.02.17
16:18
(28) нафига искать в гугле, если можно самому проверить
32 Mr_Best
 
13.02.17
16:22
(31)
Это код (функции из ссылки выше):

Ш1 = СтрЗаменить(Строка(РезультатЗапроса[0].UUID), "-", "");
Сообщить(Ш1);
Д = Из_Любой_В_10(Ш1);
Сообщить(Д);
Ш2 = Из_10_В_Любую(Д);
Сообщить(Ш2);

Это результат:
232d9a88a53011e694cdd43d7e023fd3
46 686 852 211 343 832 774 667 430 018 811 047 667
231F8F87F53010F693EEF42F6F022EF3
33 Mr_Best
 
13.02.17
16:23
(31) вот такая у меня получилась проверка, не идет. Иль я где-то ошибся ?
34 Кирпич
 
13.02.17
16:25
(33) может ошибся. может в 1с косяк какой. я знаю, что моя функция из (9) работает правильно.
35 Кирпич
 
13.02.17
16:29
(33) напиши Из_10_В_Любую(Д,16);
балда :)
36 Mr_Best
 
13.02.17
16:29
(34) а обратно конвертируется правильно ?
37 Кирпич
 
13.02.17
16:30
ты в 36 ричную переводишь
38 Mr_Best
 
13.02.17
16:30
&AtServer
Функция Из_10_В_Любую(Знач Значение=0,Нотация=16) Экспорт
     Если Нотация<=0 Тогда Возврат("") КонецЕсли;
     Значение=Число(Значение);
     Если Значение<=0 Тогда Возврат("0") КонецЕсли;
     Значение=Цел(Значение);
     Результат="";
     Пока Значение>0 Цикл
          Результат=Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Значение%Нотация+1,1)+Результат;
          Значение=Цел(Значение/Нотация) ;
     КонецЦикла;
     Возврат Результат;
КонецФункции
//_________________________________________________________
&AtServer
Функция Из_Любой_В_10(Знач Значение="0",Нотация=16) Экспорт
     Если Нотация<=0 Тогда Возврат(0) КонецЕсли;
     Значение=СокрЛП(Значение);
     Если Значение="0" Тогда Возврат(0) КонецЕсли;
     Результат=0;
     Длина=СтрДлина(Значение);
     Для Х=1 По Длина Цикл
          М=1;
          Для У=1 По Длина-Х Цикл М=М*Нотация КонецЦикла;
          Результат=Результат+(Найти("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Сред(Значение,Х,1))-1)*М;
     КонецЦикла;
     Возврат Окр(Результат);
КонецФункции

Так сойдет ?
39 Mr_Best
 
13.02.17
16:30
Я ж не совсем балда и не с перепоя :)
40 Mr_Best
 
13.02.17
16:32
Если это баг платформы, то в моей копилке это будет четвертый который я смогу легко воспроизвести :)
41 Кирпич
 
13.02.17
16:33
(40) где баг то? всё работает
42 Mr_Best
 
13.02.17
16:36
(41) что, прямо этот же самый код у вас конвертирует обратно в 16 правильно ?
43 Mr_Best
 
13.02.17
16:36
(41) и если так, какая версия платформы ?
44 Кирпич
 
13.02.17
16:37
(42) да. 8.3.9.1648
45 Sirtoo
 
13.02.17
16:41
(32)

Функция Из_Любой_В_10(Знач Значение="0",Нотация=36) Экспорт
Если Нотация<=0 Тогда Возврат(0) КонецЕсли;
Значение=СокрЛП(Значение);
Если Значение="0" Тогда Возврат(0) КонецЕсли;
Результат=0;
Длина=СтрДлина(Значение);
Для Х=1 По Длина Цикл
    М=1;
    Для У=1 По Длина-Х Цикл М=М*Нотация КонецЦикла;
    Результат=Результат+(Найти("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Сред(Значение,Х,1))-1)*М;
КонецЦикла;
Возврат Окр(Результат);
КонецФункции

Функция Из_10_В_Любую(Знач Значение=0,Нотация=36) Экспорт
Если Нотация<=0 Тогда Возврат("") КонецЕсли;
Значение=Число(Значение);
Если Значение<=0 Тогда Возврат("0") КонецЕсли;
Значение=Цел(Значение);
Результат="";
Пока Значение>0 Цикл
    Результат=Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Значение%Нотация+1,1)+Результат;
    Значение=Цел(Значение/Нотация) ;
КонецЦикла;
Возврат Результат;
КонецФункции
46 Sirtoo
 
13.02.17
16:41
как вариант.
47 Кирпич
 
13.02.17
16:46
(43) Врег() ты забыл
сразу платформу винить
48 Mr_Best
 
13.02.17
16:46
Платформа 8.3.9.2033, Клиент-Сервер

Создал новую обработку и на другой базе проверил, в обработке одна команда и код формы:


&НаСервере
Процедура НачатьНаСервере()
    
    Ш1 = Строка(Новый УникальныйИдентификатор);
    
    Сообщить(Ш1);
    Д = Из_Любой_В_10(Ш1);
    Сообщить(Д);
    Ш2 = Из_10_В_Любую(Д);
    Сообщить(Ш2);
    
КонецПроцедуры

&НаКлиенте
Процедура Начать(Команда)
    НачатьНаСервере();
КонецПроцедуры

&AtServer
Функция Из_10_В_Любую(Знач Значение=0,Нотация=16) Экспорт
     Если Нотация<=0 Тогда Возврат("") КонецЕсли;
     Значение=Число(Значение);
     Если Значение<=0 Тогда Возврат("0") КонецЕсли;
     Значение=Цел(Значение);
     Результат="";
     Пока Значение>0 Цикл
          Результат=Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Значение%Нотация+1,1)+Результат;
          Значение=Цел(Значение/Нотация) ;
     КонецЦикла;
     Возврат Результат;
КонецФункции

&AtServer
Функция Из_Любой_В_10(Знач Значение="0",Нотация=16) Экспорт
     Если Нотация<=0 Тогда Возврат(0) КонецЕсли;
     Значение=СокрЛП(Значение);
     Если Значение="0" Тогда Возврат(0) КонецЕсли;
     Результат=0;
     Длина=СтрДлина(Значение);
     Для Х=1 По Длина Цикл
          М=1;
          Для У=1 По Длина-Х Цикл М=М*Нотация КонецЦикла;
          Результат=Результат+(Найти("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Сред(Значение,Х,1))-1)*М;
     КонецЦикла;
     Возврат Окр(Результат);
КонецФункции

Результат:
4e090376-0710-43d2-9609-c398fa23caa9
5 491 141 155 062 634 646 918 224 854 143 808 955 412 217
3F090375F070FF42F1F9608EF397EF22EEF9
49 Mr_Best
 
13.02.17
16:46
Вот так !
50 Кирпич
 
13.02.17
16:47
ВРег()
балда
51 Кирпич
 
13.02.17
16:48
Гуид = СтрЗаменить(ВРег(Строка(Гуид)),"-","");
52 Mr_Best
 
13.02.17
16:56
(50) да !
Тема закрыта
53 МихаилМ
 
13.02.17
17:02
извиняюсь
гуид помещяетя в число 1с
(21) пер1 =  pow(2,128);

максимальное число

пер1 = pow(10,990000000);  
    //пер1 =  pow(2,128);
    //пер1 = 340282366920938463463374607431768211456;
    степ2 = LOG10(пер1)/LOG10(2);
    сообщить(" "+пер1);
    сообщить("__________ "+степ2);

НО лог10 с этим число не работает.
54 Кирпич
 
13.02.17
17:05
(53) в 1с не все функции с большими числами работают. я даже ВК делал одному умному чуваку, который чота вычислял большое на 1с и у него не работала функция Exp()
55 Mr_Best
 
13.02.17
22:59
Полный проверенный код, честно слизанный с статей из топика и собранный в кучу:

Функция УникальныйИдентификаторВЧисло(GUID) Экспорт

    СтрокаGUID = СтрЗаменить(Строка(GUID), "-", "");
    
    //Первая восьмерка

    ч1 = Сред(СтрокаGUID, 1, 2);

    ч2 = Сред(СтрокаGUID, 3, 2);

    ч3 = Сред(СтрокаGUID, 5, 2);

    ч4 = Сред(СтрокаGUID, 7, 2);
    
    //Первая четверка

    ч5 = Сред(СтрокаGUID, 9, 2);

    ч6 = Сред(СтрокаGUID, 11, 2);
    
    //Вторая четверка

    ч7 = Сред(СтрокаGUID, 13, 2);

    ч8 = Сред(СтрокаGUID, 15, 2);

    //Хвост

    ч9 = Сред(СтрокаGUID, 17, 16);

    СтрGUID = ч4 + ч3 + ч2 + ч1 + ч6 + ч5 + ч8 + ч7 + ч9;

    Ч = Из_Любой_В_10(СтрGUID);  

    Возврат Ч;

КонецФункции

Функция УникальныйИдентификаторИзЧисла(Ч) Экспорт
  
    СтрокаGUID = Из_10_В_Любую(Ч);
    
    //Первая восьмерка

    ч1 = Сред(СтрокаGUID, 1, 2);

    ч2 = Сред(СтрокаGUID, 3, 2);

    ч3 = Сред(СтрокаGUID, 5, 2);

    ч4 = Сред(СтрокаGUID, 7, 2);                  

    //Первая четверка

    ч5 = Сред(СтрокаGUID, 9, 2);

    ч6 = Сред(СтрокаGUID, 11, 2);  

    //Вторая четверка

    ч7 = Сред(СтрокаGUID, 13, 2);

    ч8 = Сред(СтрокаGUID, 15, 2);  

    //Хвост

    ч9 = Сред(СтрокаGUID, 17, 4);

    ч10 = Сред(СтрокаGUID, 21, 12);  

    СтрGUID = ч4 + ч3 + ч2 + ч1  + "-" + ч6 + ч5 +  "-" + ч8 + ч7 +  "-" + ч9 +  "-" + ч10;
        
    Возврат Новый УникальныйИдентификатор(СтрGUID);

КонецФункции

Функция Из_10_В_Любую(Значение, Нотация = 16) Экспорт
    
    Если Нотация <= 0 Тогда
        Возврат "";
    КонецЕсли;
    
    Значение = Число(Значение);
    
    Если Значение <= 0 Тогда
        Возврат "0";
    КонецЕсли;
    
    Значение = Цел(Значение);
    
    Результат = "";
    
    Пока Значение > 0 Цикл
        
        Результат = Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", Значение%Нотация + 1, 1) + Результат;
        Значение  = Цел(Значение/Нотация);
        
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Функция Из_Любой_В_10(Значение, Нотация = 16) Экспорт
    
    Если Нотация <= 0 Тогда
        Возврат 0;
    КонецЕсли;
    
    Значение = СокрЛП(Значение);
    
    Если Значение = "0" Тогда
        Возврат 0;
    КонецЕсли;
    
    Результат = 0;
    
    Длина = СтрДлина(Значение);
    
    Для Х = 1 По Длина Цикл
        
        М = 1;
        
        Для У = 1 По Длина - Х Цикл
            М = М * Нотация;
        КонецЦикла;
        
        Результат = Результат + (Найти("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", Сред(Значение, Х, 1)) - 1) * М;
        
    КонецЦикла;
    
    Возврат Окр(Результат);
    
КонецФункции
56 Кирпич
 
13.02.17
23:03
(55) первые две функции школьник какой то писал
57 Кирпич
 
13.02.17
23:04
нафига они вообще нужны?
58 Chikko
 
22.02.17
01:20
На тему случайно наткнулся, мб кому в будущем поможет:
в ут11 функции "ЧисловойКодПоСсылке" и "ПолучитьСсылкуПоШтрихкодуТабличногоДокумента" делают то что нужно. (типовой текст, думаю, копипастить не нужно)