Поиск в памяти
|
|
Katty | Дата: Понедельник, 26.08.2013, 03:09 | Сообщение # 1 |
Рядовой
Группа: Пользователи
Сообщений: 3
Статус: Offline
| Здравствуйте! Я только начала изучать FB и мне стало интересно, как в FB производить поиск в памяти? Например поиск строк в двоичном файле, поиск последовательности байт, поиск последовательности байт с неизвестными байтами.
|
|
| |
haav | Дата: Понедельник, 26.08.2013, 09:01 | Сообщение # 2 |
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Привет!
В любом случае из файла надо считать в буфер памяти. Алгоритмов поиска много, все зависит от задач. Вот ЗДЕСЬ можно выбрать алгоритм под свою задачу. Реализация на СИ, но даже если с СИ проблема, главное описана теория.
Цитата (Katty) Например поиск строк в двоичном файле, поиск последовательности байт
Мне ни разу не нужно было производить быстрый поиск строк в больших объемах памяти. Для моих задач вполне подходило:
Используя библиотеку window9 Считывал в память с помощью функции read_datas , преобразовывал в строковой массив с помощью peeks , а искал с помощью встроенной в freebasic функции Instr. Для моих задач скорости вполне хватало.
Для поиска отдельного двоичного символа можно применить сишную функцию memchr . Для сравнения двоичных буферов memcmp. На основе алгоритмов по ссылке выше и даже в совокупности с функциями memchr , memcmp , можно создать очень быстрый поиск. Готовые примеры я не искал, возможно на оф. форуме или на немецком сайте они есть.
Цитата (Katty) поиск последовательности байт с неизвестными байтами.
Типа поиска по маске (AA..SSS) ? Для этого однозначно надо писать свою реализацию.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
Katty | Дата: Вторник, 27.08.2013, 09:31 | Сообщение # 3 |
Рядовой
Группа: Пользователи
Сообщений: 3
Статус: Offline
| haav, спасибо за ответ. Пойду изучать. А вот у VB6 есть такая функция Like наподобие регулярных выражений, вот ей можно искать в бинарном файле. А у FB есть что-то подобное?
|
|
| |
haav | Дата: Вторник, 27.08.2013, 10:58 | Сообщение # 4 |
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Цитата (Katty) А вот у VB6 есть такая функция Like наподобие регулярных выражений, вот ей можно искать в бинарном файле. А у FB есть что-то подобное?
У FreeBasic есть только функции Instr и InstrRev для поиска подстроки в строке.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
Katty | Дата: Четверг, 29.08.2013, 08:31 | Сообщение # 5 |
Рядовой
Группа: Пользователи
Сообщений: 3
Статус: Offline
| >У FreeBasic есть только функции Instr и InstrRev для поиска подстроки в строке. А регулярных выражений нет совсем?
|
|
| |
haav | Дата: Четверг, 29.08.2013, 10:33 | Сообщение # 6 |
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Статус: Offline
| Цитата (Katty) А регулярных выражений нет совсем?
В самом языке нет. Но можно подключить библиотеку TRE.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
ShadEx | Дата: Суббота, 31.08.2013, 14:25 | Сообщение # 7 |
Лейтенант
Группа: Проверенные
Сообщений: 51
Статус: Offline
| Ну, если только простой поиск по маске, то регулярками искать слишком затратно будет, тем более в бинарных файлах... Лучше wildcard использовать:
Код Declare Function checkWildcard (wildcard As String, checkStr As String, caseMode As Integer = 0) As Integer
Function repStr (mainStr As String, findStr As String, replaceStr As String) As String Dim As String retVal If mainStr = "" Then Return "" If findStr = "" Then Return mainStr
For i As uInteger = 1 To Len(mainStr) If Mid(mainStr, i, Len(findStr)) = findStr Then retVal = retVal + replaceStr i += Len(findStr)-1 Else retVal = retVal + Chr(mainStr[i-1]) End If Next i Return retVal End Function
Function isAlphanumeric (char As uByte) As Integer If char < Asc("0") Then Return 0 If char < Asc("9") Then Return 1 If char < Asc("A") Then Return 0 If char < Asc("Z") Then Return 1 If char < Asc("a") Then Return 0 If char < Asc("z") Then Return 1 Return 0 End Function
Function checkWildcard (wildcard As String, checkStr As String, caseMode As Integer = 0) As Integer Dim As Integer i = 0, j = 0 Dim As Integer found Dim As Integer tmp
'Case mode: 0 = case-insensitive, non-zero = case-sensitive If caseMode = 0 Then 'Case-insensitive just means both strings are converted to lowercase 'before the wildcard comparison is performed. wildcard = LCase(wildcard) checkStr = LCase(checkStr) End If
'If the wildcard string is *, return 0 no matter what because it will match 'anything and everything If wildcard = "*" Then Return 1
'Keep replacing until there's nothing left to replace 'Turns a run of "*" characters (such as "*****") into a single "*" Do tmp = Len(wildcard) wildcard = repStr(wildcard, "**", "*") Loop While Len(wildcard) < tmp
'Continue as long as there's anything left to both strings Do While (i < Len(checkStr)) And (j < Len(wildcard)) 'If we find a ? alphanumeric wildcard If wildcard [j]= Asc("?") Then 'If the next character is not alphanumeric, return mismatch If isAlphanumeric(checkStr[i]) = 0 Then Return 0 End If 'Otherwise, go to the next character in both strings i += 1 j += 1 'If we find a * wildcard ElseIf wildcard [j]= Asc("*") Then 'If we're at the end of the wildcard string return TRUE 'because wildcard matches anything that could be beyond. If j = Len(wildcard) Then Return 1
'Otherwise, search the string being checked for the character 'following the wildcard. Do Until checkStr [i]= wildcard[j+1] 'Skip over every character until we get to that one i += 1 Loop 'We only skip one character - the wildcard j += 1 'If there's simply a mismatch, return FALSE ElseIf wildcard [j]<> checkStr [i]Then Return 0 Else 'But if it's a regular character which matches in both, 'skip both characters in both strings i += 1 j += 1 End If
'If we reach the end of the wildcard before the main string, return FALSE If (i < Len(checkStr)) And (j >= Len(wildcard)) Then Return 0
'If we reach the end of the main string before the end of the wildcard, 'check if we're on the last character of the wildcard and if it's a * 'if either condition is false, return FALSE - otherwise return TRUE. If (i >= Len(checkStr)) And (j < Len(wildcard)) Then If j = Len(wildcard)-1 Then If wildcard [j]= Asc("*") Then Return 1 End If Return 0 End If Loop
'Anything that has made it to the end like this must be matching Return 1 End Function
Dim bin_string as String = Chr(127)+"Сьешь еще этих" +Chr(8)+ "мягких французких булок да выпей чаю."+Chr(10) bin_string &= Chr(127)+"The quick brown fox" + Chr(127) + "jumps over the lazy dog"
? bin_string ? checkWildcard("*мягких*чаю*the*jump*do?", bin_string) ? checkWildcard("*мягких*чаю*the*jump*do?", bin_string,1) ? checkWildcard("*мягких*чаю*The*jump*do?", bin_string,1) Sleep Ну и конечно же это только для однобайтовых кодировок.
|
|
| |