Преобразуем Ip адрес в число и обратно

SlavikSG
Дата: 16.02.2016 10:40:45
Всем привет!

Почему-то я не смог найти в Microsoft Access на чистом Visual Basic ни одного живого и до конца написанного примера перевода строкового IP-адреса в число и обратно. Находил примеры только на других языках. В результате родились две функции такого вида:

' Преобразуем число в строковый IP-адрес
Function Ip_to_String(Sss As Long)

Dim R1 As Double
Dim R2 As Double
Dim R3 As Double
Dim R4 As Double

R1 = Int(Sss / 256 / 256 / 256) 'Определяем 1 октет IP-адреса
R2 = Int((Sss - R1 * 256 * 256 * 256) / 256 / 256) 'Определяем 2 октет IP-адреса
R3 = Int((Sss - R1 * 256 * 256 * 256 - R2 * 256 * 256) / 256) 'Определяем 3 октет IP-адреса
R4 = Int(Sss - R1 * 256 * 256 * 256 - R2 * 256 * 256 - R3 * 256) 'Определяем 4 октет IP-адреса

'Сливаем все в одну кучу
Ip_to_String = Trim(Str(R1)) & "." & Trim(Str(R2)) & "." & Trim(Str(R3) & "." & Trim(Str(R4)))

End Function


' Преобразуем строковый IP-адрес в число
Function Ip_to_Integer(Sss As String)

Dim N1 As Byte
Dim N2 As Byte
Dim N3 As Byte

N1 = InStr(1, Sss, ".") ' Находим положение первой точки
N2 = InStr(N1 + 1, Sss, ".") ' Находим положение второй точки
N3 = InStr(N2 + 1, Sss, ".") ' Находим положение третьей точки

'Сливаем все в одну кучуIp_to_Integer = Mid(Sss, 1, N1 - 1) * 256 * 256 * 256 + Mid(Sss, N1 + 1, N2 - N1 - 1) * 256 * 256 + Mid(Sss, N2 + 1, N3 - N2 - 1) * 256 + Mid(Sss, N3 + 1, Len(Sss) - N3)

End Function


Вопрос заключается в том, правильно ли я все сделал? Не будет ли тормозить такой алгоритм в запросах при обращении к большим таблицам? Может есть какое-то более быстрое и гибкое решение? Подскажите, плиииз!
Akina
Дата: 16.02.2016 11:13:54
IP-адрес по сути это 32-битное беззнаковое целое. И преобразование его "в число и обратно" звучит как минимум странненько.

SlavikSG
Не будет ли тормозить такой алгоритм в запросах при обращении к большим таблицам?

Будет.

SlavikSG
Может есть какое-то более быстрое и гибкое решение?

В таблицах и запросах иметь дело ТОЛЬКО с binary(32) aka Long. А преобразования в строку и обратно использовать только на стадии ввода/вывода.
13-й квартал
Дата: 16.02.2016 11:31:05
SlavikSG
Вопрос заключается в том, правильно ли я все сделал?
Очевидно, неправильно:
?Ip_to_String(&hc00002eb)
-64.0.2.235
Можно воспользоваться LSet:
Private Type TLong
   l As Long
End Type

Private Type TQuadByte
   b(0 To 3) As Byte
End Type

Function Ip_to_String2(Sss As Long) As String
 Dim l As TLong
 Dim qb As TQuadByte
 l.l = Sss
 LSet qb = l
 'Сливаем все в одну кучу
 Ip_to_String2 = Format(qb.b(3)) & "." & Format(qb.b(2)) & "." & Format(qb.b(1)) & "." & Format(qb.b(0))
End Function


Как уже указали, функции для форматирования в читабельный человеком вид нужны для представления результата человеку :)
SlavikSG
Дата: 17.03.2016 17:11:49
Большое спасибо! Я понял. :)

Инструкцию LSet я точно не догадался бы применить. Но теперь другая заковыка. Никак не могу сообразить, как грамотно сделать обратное преобразование. Как из строкового IP-адреса получить число Long не прибегая к ручной и медленной обработки строки Ip-адреса?
\\\\
Дата: 17.03.2016 19:27:17
SlavikSG, по аналогии с предыдущим примером
Function Ip_to_Long(Sss As String) As Long
 Dim l As TLong
 Dim qb As TQuadByte
 Dim varArray As Variant
 Dim i As Long
On Error Resume Next
 varArray = Split(Sss, ".")
    For i = 0 To 3
        qb.b(i) = varArray(3 - i)
    Next i
Erase varArray
LSet l = qb
Ip_to_Long = l.l
End Function
SlavikSG
Дата: 18.03.2016 14:13:13
А в "Microsoft Access 97" есть функция spilt? Чет у меня ошибку выдает. И в хелпе ее нет. :(
guest_rusimport
Дата: 18.03.2016 14:33:53
SlavikSG
А в "Microsoft Access 97" есть функция spilt? Чет у меня ошибку выдает. И в хелпе ее нет. :(

в 97-м split нет, но можно воспользоваться этим -
http://am.rusimport.ru/msaccess/f2.aspx?id=25860
SlavikSG
Дата: 18.03.2016 15:15:11
Ага. Понял. Спасибо! :)