Рассчёт чексума IMEI

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
xqz_me
Постоялец
Постоялец
 
Сообщения: 413
Зарегистрирован: 04.12.2005 (Вс) 14:58

Рассчёт чексума IMEI

Сообщение xqz_me » 05.12.2005 (Пн) 17:32

Сразу хочется сказать, что ничего плохого в этой идеи нет. Просто захотел написать программу, которая будет проверять, реальний ли у телефона IMEI, или телефон левый. Для справки, IMEI - уникальный идентификатор аппарата, состоящий из 15 цифр, посмотреть который можно, набрав *#06#

Суть такая. В программу нужно вести первые 14 цифр imei, а она рассчитает по нехитрому алгоритму последнюю. Если она совпадёт с той, что в телефоне, то всё нормально, если нет - то аппарат левый.

Последняя цифра рассчитывается по такому алгоритму:
Calculation of CD (Luhn Check Digit):
Step 1: Double the values of the odd labelled digits D1, D3, ... D13.
Step 2: Add together the individual digits of all the seven numbers
obtained in Step 1, and then add this sum to the sum of all the even
labelled digits D2, D4, D6 ... D14 of the IMEI.
Step 3: If the number obtained in Step 2 ends in 0, then set CD to be
0. If the number obtained in Step 2 does not end in 0, then set CD to
be that number subtracted from the next higher number which does end
in 0.


Как бы его покрасивей реализовать?

vvs_adm
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1492
Зарегистрирован: 03.02.2005 (Чт) 3:45
Откуда: оттуда ;)

Re: Рассчёт чексума IMEI

Сообщение vvs_adm » 05.12.2005 (Пн) 19:07

xqz_me писал(а):Как бы его покрасивей реализовать?
Ну сделай форму в виде цветка, по тычинкам раскидываешь свои 15 цифр и жмешь на лепесток. Если неправильно - цветок завянет с последующим форматированием винчестера... :lol:
Никогда не откладывай на завтра то, что можно ... отложить на послезавтра!

xqz_me
Постоялец
Постоялец
 
Сообщения: 413
Зарегистрирован: 04.12.2005 (Вс) 14:58

Сообщение xqz_me » 05.12.2005 (Пн) 20:27

Дельное предложение :)
А всё-таки?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Рассчёт чексума IMEI

Сообщение alibek » 06.12.2005 (Вт) 8:30

vvs_adm писал(а):Ну сделай форму в виде цветка, по тычинкам раскидываешь свои 15 цифр и жмешь на лепесток.

:shock:
Хорошо, что сюда биологи не заходят, а то несчастных случаев не миновать.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 06.12.2005 (Вт) 8:51

Если я правильно понял перевод, то так:
Код: Выделить всё
Function Calc_IMEI_CD(ByVal IMEI As String) As String
Dim D As String, P As Long, res1 As Long, res2 As Long, S As String
For P = 1 To 14 Step 2
  res1 = res1 + Val(Mid$(IMEI, P, 1))
  res2 = res2 + Val(Mid$(IMEI, P+1, 1))
Next P
res = Trim$(Str$(2 * res1 + res2))
If Right$(S, 1) = "0" Then
  D = "0"
Else
  For P = Len(S) To 1 Step -1
    If Mid$(S, P, 1) = "0" Then
      D = Mid$(S, P-1, 1)
    End If
  Next P
End If
Calc_IMEI_CD = D
End Function
Lasciate ogni speranza, voi ch'entrate.

xqz_me
Постоялец
Постоялец
 
Сообщения: 413
Зарегистрирован: 04.12.2005 (Вс) 14:58

Сообщение xqz_me » 06.12.2005 (Вт) 13:14

Я не очень понял

Код: Выделить всё
Function Calc_IMEI_CD(ByVal IMEI As String) As String
Dim D As String, P As Long, res1 As Long, res2 As Long, S As String
For P = 1 To 14 Step 2
  res1 = res1 + Val(Mid$(IMEI, P, 1))
  res2 = res2 + Val(Mid$(IMEI, P + 1, 1))
Next P
res = Trim$(Str$(2 * res1 + res2))
If Right$(S, 1) = "0" Then
  D = "0"
Else
  For P = Len(S) To 1 Step -1
    If Mid$(S, P, 1) = "0" Then
      D = Mid$(S, P - 1, 1)
    End If
  Next P
End If
Calc_IMEI_CD = D
End Function

Private Sub Command1_Click()
IMEI = "12345678901234"
MsgBox IMEI + CStr(Calc_IMEI_CD(IMEI))

End Sub


Почему так не возвращает последнюю цифру?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 06.12.2005 (Вт) 14:26

Значит я неправильно понял алгоритм.
Опиши его на русском языке.
Lasciate ogni speranza, voi ch'entrate.

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 06.12.2005 (Вт) 16:53

....... и в полночь, на перекрестке семи дорог, под тенью от сучка старого дуба...

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 06.12.2005 (Вт) 17:10

Я тут чего-то правильных IMEI не видел...
Вот может поможет кому: 352206-00-424125-0

xqz_me
Постоялец
Постоялец
 
Сообщения: 413
Зарегистрирован: 04.12.2005 (Вс) 14:58

Сообщение xqz_me » 06.12.2005 (Вт) 18:46

Значит я неправильно понял алгоритм.

Может быть. Толька твоя функция ничего не возвращает. Или я тормажу.

Опиши его на русском языке.

Сам не до конца врубился.

Есть аналогичные проги на Паскале:
Код: Выделить всё
function KeyGen(Name: string): string;
var
    Len : DWord;
  I,J,CRC: Integer;
  Words00: array[1..16] of Byte;
  Words01: array[1..20] of Byte;
  BP06,BP0E,BP0C :Byte ;   
begin
  Len := length(Name);
  if(Len=14)OR(Len=15) then
  begin
  For I := 1 to 14 Do
   begin
     BP06:=CopyNum(Name[I]);
     if(BP06=10) then begin
                 Result:='xxxxxxxxxxxxxxx';
                 exit;
                 end;
     Words00[I] := BP06;
   end;
  Words00[15]:=0;
  I := 1;
  J := 1;
  While I<16 Do
    Begin
      If (I Mod 2) <> 0 Then
        Words01[J] := Words00[I]
      Else
        Begin
          BP06 := (Words00[I] Shl 01);
          If BP06 <= 09 Then Words01[J] := BP06
            Else
              Begin
                BP0C := (BP06 Mod 10);
                BP0E := (BP06 Div 10);
                Words01[J] := BP0E;
                Words01[J+1] := BP0C;
                Inc(J);
              End;
        End;
      Inc(I);
      Inc(J);
    End;
   CRC := 0;
   I:=1;
   While I < J Do
    Begin
      CRC := CRC + Words01[I];
      Inc(I);
    End;
    BP06 := (CRC Mod 10);
    BP0C := (CRC Div 10);
    If BP06 = 0 Then Words00[15] := 0
                Else Words00[15] := (BP0C+1)*10-CRC;
    I:=1;
    Result:='';
    While I < 16 Do begin
    Result:=Result+ByteToChar(Words00[I]);
    Inc(I);
    end;
end
else Result := 'xxxxxxxxxxxxxxx';
end;


На Си

Код: Выделить всё
int     i,j,sum;
char    imei[14],a[7];

main(int argc, char **argv)
{
if(argc != 15) {
        printf("IMEI has 14 digits ...\n");
        exit(0);
        }
for(i=0;i<=13;i++) {
        imei[i] = (unsigned char) atoi(argv[i+1]);
        }

for (i=1,j=0;i<=13;i+=2) a[j++]=imei[i]*2;                     /* Step 1 */
for (i=sum=0;i<=6;i++) sum += sod(a[i]);                       /* Step 2 */
for (i=0;i<=12;i+=2) sum += imei[i];

printf("IMEI:\t");
for (i=0;i<=13;i++) printf("%d", imei[i]);

if( ( ((int) sum / 10 ) * 10 ) == sum ) printf(" - 0\n");      /* Step 3 */
else printf(" - %d\n", ((int) sum / 10 + 1) * 10 - sum);
}

sod(int wert)           /* sum of the digits */
{
  int a,b;
  a = (int) wert / 10;
  b = (int) ((wert * 10) - a * 100 ) / 10;
  return a+b;
}


И даже на самом VB. Тока я там ничего не понял, какая переменная за что отвечает

Код: Выделить всё
For I1 = 1 To Len(S1) Step 2
            L1 = L1 + Val(Mid(S1, I1, 1))
        Next I1
           
        For I1 = 2 To Len(S1) Step 2
            I2 = Val(Mid(S1, I1, 1)) * 2
            If I2 < 10 Then
                L1 = L1 + I2
            Else
                L1 = L1 + Val(Mid(Trim(Str(I2)), 1, 1))
                L1 = L1 + Val(Mid(Trim(Str(I2)), 2, 1))
            End If
        Next I1
               
        If Int(L1 / 10) * 10 = L1 Then
            Label3(5).Caption = "0"
        Else
            Label3(5).Caption = Trim(Str((Int(L1 / 10) + 1) * 10 - L1))
        End If


Собственно, брал всё отсюда (они там ещё пример конкретный разбирают):
http://www.gsmlab.com/forum/viewtopic.php?p=65014

Поможете?

xqz_me
Постоялец
Постоялец
 
Сообщения: 413
Зарегистрирован: 04.12.2005 (Вс) 14:58

Сообщение xqz_me » 07.12.2005 (Ср) 10:58

Ну так чё, поможет кто-нибудь? :(

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 07.12.2005 (Ср) 11:07

Тут и разбираться не надо: поправил и всё :)
Код: Выделить всё

Option Explicit
Private Sub Form_Load()
MsgBox LastIMEI("35220600424125")
End Sub

Private Function LastIMEI(IMEI As String) As String
Dim L1 As Long
Dim I1 As Long
Dim I2 As Long
Dim S1 As String
S1 = IMEI
For I1 = 1 To Len(S1) Step 2
            L1 = L1 + Val(Mid(S1, I1, 1))
        Next I1
           
        For I1 = 2 To Len(S1) Step 2
            I2 = Val(Mid(S1, I1, 1)) * 2
            If I2 < 10 Then
                L1 = L1 + I2
            Else
                L1 = L1 + Val(Mid(Trim(Str(I2)), 1, 1))
                L1 = L1 + Val(Mid(Trim(Str(I2)), 2, 1))
            End If
        Next I1
               
        If Int(L1 / 10) * 10 = L1 Then
            LastIMEI = "0"
        Else
            LastIMEI = Trim(Str((Int(L1 / 10) + 1) * 10 - L1))
        End If
End Function


Только проверь надругих IMEI, тип L1 неясен...
Изображение


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 42

    TopList