1 (изменено: akhill, 2014-11-17 21:59:30)

Тема: AHK: Кириллица в URL

Привет!
Возникла необходимость программной вставки в строку URL параметров в виде строк текста, превращенных в шестнадцатиричную форму (некоторые сайты требуют для корректной обработки поиска в своих базах). Т. е. нужно например найти "Вася", но в поисковую строку вставить в виде %22%C2%E0%F1%FF%22 (чтобы было например:www.google.com/search?q=%22%C2%E0%F1%FF%22).
Написал функцию,

SetFormat, integer, H 
ToURL(str)
{
;str := Utf8ToAnsi(s)
sl := StrLen(str)
i := 1
result =
while i <= sl
{
hex := Asc(Substr(str, i, 1))
s := Substr(hex, 3)
result .= `% . s 
;MsgBox, %result% `n %i% из %sl% `n %s% - %str%
i ++
} 
return result
}

но при отладке понял что возникает необходимость конвертации кириллицы из unicode в ansi, поскольку Asc на кириллице выдает 0xXXX, с которыми мне не понятно что делать потом.
Предлагаемая в форуме Utf8ToAnsi() почему-то не работает в моей 7х64. Может кто-нибудь сталкивался. Посоветуйте что-нибудь. Буду рад.

2

Re: AHK: Кириллица в URL

Я пользуюсь таким вариантом:

text := "поисковый запрос кириллица"
GoogleSearch := "https://www.google.ru/search?q="

MsgBox, % url := GoogleSearch . URIEncode(text)
Run, % url

URIEncode(Str)
{
   b_Format:=A_FormatInteger
   SetFormat, IntegerFast, H
   Loop, % StrPutVar(Str, Var, "UTF-8")
   {
      Ch:=NumGet(Var, A_Index-1, "UChar")
      If Ch=0
         Break
      If (Ch>0x7f Or Ch<0x30 Or Ch=0x3d)
         s.="%"((StrLen(c:=SubStr(Ch, 3))<2) ? "0"c:c)
      else
         s.=Chr(Ch)
   }
   SetFormat, IntegerFast, % b_Format
   Return, s
}

StrPutVar(string, ByRef var, encoding = "CP0")
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: akhill, 2014-11-17 23:34:45)

Re: AHK: Кириллица в URL

@teadrinker
Пример хороший, но он не решает проблемы (UTF-16 или 8 в Ansi) поскольку в целевом сайте в строку поиска вставляется "необходимость" вместо "необходимость" Хотя в URL отображаеся «..index.php?q="необходимость"&where=..». Мне все-таки нужна Ansi строка на выходе для корректрой работы по крайней мере на этом сайте. Или я чего-то не понимаю.

4

Re: AHK: Кириллица в URL

Попробуйте так:

text := "поисковый запрос кириллица"
GoogleSearch := "https://www.google.ru/search?q="

MsgBox, % url := GoogleSearch . URIEncode(text, "CP0")
Run, % url

URIEncode(Str, coding)
{
   b_Format:=A_FormatInteger
   SetFormat, IntegerFast, H
   Loop, % StrPutVar(Str, Var, coding)
   {
      Ch:=NumGet(Var, A_Index-1, "UChar")
      If Ch=0
         Break
      If (Ch>0x7f Or Ch<0x30 Or Ch=0x3d)
         s.="%"((StrLen(c:=SubStr(Ch, 3))<2) ? "0"c:c)
      else
         s.=Chr(Ch)
   }
   SetFormat, IntegerFast, % b_Format
   Return, s
}

StrPutVar(string, ByRef var, encoding = "CP0")
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: akhill, 2014-11-18 00:31:49)

Re: AHK: Кириллица в URL

@teadrinker
Да, спасибо! Счас -- то, что надо.
Поучительный пример. Еще раз спасибо.

6

Re: AHK: Кириллица в URL

Предлагаю пример в Коллекцию. Это становится актуально.

7

Re: AHK: Кириллица в URL

Можно, хотя я так и не понял, в каких конкретно случаях требуется конвертировать в ANSI.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Кириллица в URL

Тоже не понял в каких случаях, но если пример универсален, то поддерживаю, надо в коллекцию.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9

Re: AHK: Кириллица в URL

Немного сократил:

text := """кодировка URL"""
GoogleSearch := "https://www.google.ru/search?q="

MsgBox, % url := GoogleSearch . URIEncode(text)
Run, % url

URIEncode(str, encoding := "UTF-8")
{
   PrevFormat := A_FormatInteger
   SetFormat, IntegerFast, H
; кодируем стоку в указанную кодировку с помощью StrPut()
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)
; последовательно перебирая символы, кодируем их в URL-формат   
   While code := NumGet(Var, A_Index - 1, "UChar")   ; пока code не равно 0, что означает конец строки
   {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)   ; отсеиваем символы, которые кодировать не нужно
      UrlStr .= bool ? "%" . SubStr("0" . SubStr(code, 3), -1) : Chr(code)
   }
   SetFormat, IntegerFast, % PrevFormat
   Return UrlStr
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10 (изменено: serzh82saratov, 2015-08-23 23:13:49)

Re: AHK: Кириллица в URL

Пара вопросов.
Сократил запись (хлебом не корми):


URIEncode(str, encoding := "UTF-8") {  
    VarSetCapacity(var, StrPut(str, encoding)), StrPut(str, &var, encoding) 
    While code := NumGet(Var, A_Index - 1, "UChar")
        UrlStr .= (code > 0x7F || code < 0x30 || code = 0x3D) ? Format("%{:02X}", code) : Chr(code) 
    Return UrlStr
}

Есть ли ошибки, и смущает расхождение с оригиналом:

SubStr("0" . SubStr(code, 3), -1)


После процента обязательно должно быть 2 знака?

И для общего развития, по поводу индекса в Unicode и значений байтов (собственно а есть ли тут связь?).

SetFormat, IntegerFast, h
 ; в комментариях значения как и в NumGet
str :=  ","  
MsgBox, % Ord(str) ; 0x2c

str :=  "Ё" 
MsgBox, % Ord(str) ; 0xd0 & 0x81

С первым MsgBox понятно, а во втором число 0x401 как то логично "разбивается" на 0xd0 & 0x81?

Ап: По поводу:

После процента обязательно должно быть 2 знака?

Разобрался, поправил.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Кириллица в URL

С первым MsgBox понятно, а во втором число 0x401 как то логично "разбивается" на 0xd0 & 0x81?

Ё = 0x401 — это UTF-16, а %D0%81 — это UTF-8.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Кириллица в URL

Теперь ещё более непонятно, 0xD0 и 0x81 это цифровое представление двух байт в UTF-8.?
А какая связь 0x401 и UTF-16?  В UTF-16 кажется 4 байта на символ, да и 0x401 не может быть представлением байта.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

13

Re: AHK: Кириллица в URL

UTF-16 — 2 байта на символ (16 бит).

SetFormat, IntegerFast, H
str := "ЁЁ"
MsgBox, % NumGet(&str, "UInt")
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

14

Re: AHK: Кириллица в URL

SetFormat, IntegerFast, H
str := "ЁЁ"
VarSetCapacity(var, StrPut(str, "UTF-8"))
StrPut(str, &var, "UTF-8")
MsgBox, % NumGet(var, "UInt")
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Кириллица в URL

UTF-16 — 2 байта на символ (16 бит).

Но может быть и 4?

wikipedia пишет:

Один символ кодировки UTF-16 представлен последовательностью двух байтов или двух пар байтов

Ещё меньше понимаю что за 1 потом 4 в этом коде:

SetFormat, IntegerFast, H
str := "Ё" 
encoding := "UTF-16" 
VarSetCapacity(var, StrPut(str, encoding))
StrPut(str, &var, encoding) 
While code := NumGet(Var, A_Index - 1, "UChar")
    MsgBox, % code
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16

Re: AHK: Кириллица в URL

А, ну да, может быть и четыре для всяких символов типа арабских. В AHK-Unicode строки кодируются в UTF-16, так что

encoding := "UTF-16" 
VarSetCapacity(var, StrPut(str, encoding))
StrPut(str, &var, encoding) 

не нужно.

SetFormat, IntegerFast, H
str := "Ё" 

While code := NumGet(str, A_Index - 1, "UChar")
    MsgBox, % code

0x1 — это 0x01
0x4 — это 0x04
Вместе 0x0401

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Кириллица в URL

0x1 — это 0x01
0x4 — это 0x04
Вместе 0x0401

Жутко не понятно, почему не по порядку - 0x0104.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

18

Re: AHK: Кириллица в URL

Чтение идёт от младших байтов к старшим.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Кириллица в URL

Туго у меня с этим делом... Например почему в случае с "перебором" байтов в "UTF-8" всё по порядку?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20 (изменено: teadrinker, 2015-08-24 03:42:03)

Re: AHK: Кириллица в URL

Одинаково:

SetFormat, IntegerFast, H
str := "ЁЁ"
MsgBox, % NumGet(str, "UInt")
While code := NumGet(str, A_Index - 1, "UChar")
    MsgBox, % code

VarSetCapacity(var, StrPut(str, "UTF-8"))
StrPut(str, &var, "UTF-8")
MsgBox, % NumGet(var, "UInt")

While code := NumGet(var, A_Index - 1, "UChar")
    MsgBox, % code

В UTF-8 Ё — 0x81D0, a в URL — в обратном порядке: %D0%81

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder