├── Huawei.go ├── main.go ├── README.md ├── Blackberry.go ├── ZTE.go └── Alcatel.go /Huawei.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "io" 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func HuaweiOld(imei string) []string { 12 | preUCSalt := md5.New() 13 | preFCSalt := md5.New() 14 | io.WriteString(preUCSalt,"hwe620datacard") 15 | io.WriteString(preFCSalt,"e630upgrade") 16 | pre2UCSalt := fmt.Sprintf("%x", preUCSalt.Sum(nil)) 17 | pre2FCSalt := fmt.Sprintf("%x", preFCSalt.Sum(nil)) 18 | fmt.Println(pre2UCSalt + " && " + pre2FCSalt) 19 | out := "Unlock: " + HuaweiCode(imei, pre2UCSalt[8:24]) + " Flash:" + HuaweiCode(imei, pre2FCSalt[8:24]) 20 | return strings.Fields(out) 21 | } 22 | 23 | func HuaweiCode(imei string,salt string) string { 24 | var ( 25 | //imei = "123456789012347" 26 | appByte []byte 27 | ) 28 | preIn := imei+salt//"5e8dd316726b0335" 29 | mySum := md5.New() 30 | io.WriteString(mySum, preIn) 31 | myByte := mySum.Sum(nil) 32 | appByte = append(appByte,(myByte[0] ^ myByte[4] ^ myByte[8] ^ myByte[12]),(myByte[1] ^ myByte[5] ^ myByte[9] ^ myByte[13]),(myByte[2] ^ myByte[6] ^ myByte[10] ^ myByte[14]),(myByte[3] ^ myByte[7] ^ myByte[11] ^ myByte[15])) 33 | part1 := []byte{0x1, 0xff, 0xff, 0xff} 34 | part2 := []byte{0x2, 0x00, 0x00, 00} 35 | appByte = []byte{(appByte[0] & part1[0]), (appByte[1] & part1[1]),(appByte[2] & part1[2]),(appByte[3] & part1[3])} 36 | appByte = []byte{(appByte[0] | part2[0]), (appByte[1] | part2[1]),(appByte[2] | part2[2]),(appByte[3] | part2[3])} 37 | preout := fmt.Sprintf("%x",appByte) 38 | out,err := strconv.ParseUint(preout,16,64) 39 | if err != nil{ 40 | panic(err) 41 | } 42 | return strconv.FormatUint(out,10) 43 | } 44 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "encoding/json" 7 | "strings" 8 | ) 9 | 10 | func outJSON(src string, YesNo string) []byte{ 11 | prep := src[0:len(src)-1] 12 | preout := strings.Split(prep, ",") 13 | out,err := json.Marshal(preout) 14 | if err != nil{ 15 | panic(err) 16 | } 17 | return out 18 | } 19 | 20 | func main() { 21 | userArgs := os.Args 22 | if userArgs[1] == "todo" { 23 | todo() 24 | } 25 | if userArgs[1] == "blackberryMEP" { 26 | if userArgs[2] == "unlock" { 27 | preout := Blackberry(userArgs[3], userArgs[4]) 28 | out := outJSON(preout) 29 | fmt.Println(string(out)) 30 | } 31 | if userArgs[2] == "getSupported" { 32 | out,err := json.Marshal(getSupported("MEP")) 33 | if err != nil{ 34 | panic(err) 35 | } 36 | fmt.Println(string(out)) 37 | } 38 | } 39 | if userArgs[1] == "blackberryPRD" { 40 | if userArgs[2] == "unlock" { 41 | preout := Blackberry(userArgs[3], userArgs[4]) 42 | out := outJSON(preout) 43 | fmt.Println(string(out)) 44 | } 45 | if userArgs[2] == "getSupported" { 46 | out,err := json.Marshal(getSupported("PRD")) 47 | if err != nil{ 48 | panic(err) 49 | } 50 | fmt.Println(string(out)) 51 | } 52 | } 53 | if userArgs[1] == "huaweiOld" { 54 | if userArgs[2] == "unlock" { 55 | out,err := json.Marshal(HuaweiOld(userArgs[3])) 56 | if err != nil{ 57 | panic(err) 58 | } 59 | fmt.Println(string(out)) 60 | } 61 | } 62 | if userArgs[1] == "zteOld" { 63 | if userArgs[2] == "unlock" { 64 | out,err := json.Marshal(zteOld(userArgs[3])) 65 | if err != nil{ 66 | panic(err) 67 | } 68 | fmt.Println(string(out)) 69 | } 70 | } 71 | if userArgs[1] == "zteB03" { 72 | if userArgs[2] == "unlock" { 73 | out,err := json.Marshal(zteB03(userArgs[3])) 74 | if err != nil{ 75 | panic(err) 76 | } 77 | fmt.Println(string(out)) 78 | } 79 | } 80 | if userArgs[1] == "zteB04" { 81 | if userArgs[2] == "unlock" { 82 | out,err := json.Marshal(zteB04(userArgs[3])) 83 | if err != nil{ 84 | panic(err) 85 | } 86 | fmt.Println(string(out)) 87 | } 88 | } 89 | if userArgs[1] == "alcatelC700" { 90 | if userArgs[2] == "unlock" { 91 | out,err := json.Marshal(alcatelC700(userArgs[3], userArgs[4])) 92 | if err != nil{ 93 | panic(err) 94 | } 95 | fmt.Println(string(out)) 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unlock Code Calculator in GoLang # 2 | 3 | ## Intro 4 | These are scripts that can be used to calculate unlock codes for various different mobile phones. I'll work on adding a list of supported models but for now, I'm just getting this code up here. Contributions to this repository of any kind are more than welcome, I'm new to GoLang so I'd love to see what I could have done better. 5 | 6 | 7 | ## Features 8 | **Blackberry** - Can calculate codes for 231 MEPs and ~7000 different PRDs. See findMEP.go 9 | 10 | **Huawei** - Works with older USB modems. 11 | 12 | **ZTE** - Three different calculators, one for old models, one calculates codes for firmware B03, the other calculates codes for firmware B04. 13 | 14 | **Alcatel** - The models this will calculate codes for are commented into Alcatel.go. I'll probably move them into the README in my next commit. 15 | 16 | **JSON output** - I really like the look of JSON. Some people might find it annoying though and I'll probably either remove it or make it optional later. 17 | 18 | ## Usage 19 | Check out main.go, use with command line arguments. 20 | 21 | ##Disclaimer 22 | This code is intended to be used for eductational purposes and comes with no guarantees of anything. In the USA it is illegal to unlock any phone purchased AFTER January 26th, 2013 without the carrier's permission. 23 | 24 | ##Legal 25 | The MIT License (MIT) 26 | Copyright (c) 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 29 | 30 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 | -------------------------------------------------------------------------------- /Blackberry.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/hex" 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func createPrivatePass(MEP [16]int) [64]int { 12 | arrayStatic := [16]int{0x16, 0x27, 0x99, 0xC2, 0xC8, 0x99, 0xB8, 0xC9, 0xDE, 0xED, 0x77, 0xA2, 0x62, 0xD2, 0x66, 0x5E} 13 | Pass := [64]int{} 14 | for i := 0; i < 16; i++ { 15 | Pass[i] = arrayStatic[i] ^ MEP[i] 16 | } 17 | return Pass 18 | } 19 | 20 | func makeSHA1(strIMEI string, pPass [64]int, mepNumber int) string { //generates SHA1 21 | var ( 22 | imei = fmt.Sprintf("%02X", strIMEI) + "0" + strconv.Itoa(mepNumber) 23 | o_key = [64]string{} 24 | i_key = [64]string{} 25 | o_key_pad = "" 26 | i_key_pad = "" 27 | ) 28 | for i := 0; i < 64; i++ { 29 | o_key[i] = fmt.Sprintf("%02X", pPass[i]^0x5C) 30 | i_key[i] = fmt.Sprintf("%02X", pPass[i]^0x36) 31 | o_key_pad += o_key[i] 32 | i_key_pad += i_key[i] 33 | } 34 | p1inputSha1 := i_key_pad + imei 35 | p1digest := sha1digest(p1inputSha1) 36 | p2inputSha1 := o_key_pad + p1digest 37 | p2digest := sha1digest(p2inputSha1) 38 | return p2digest 39 | } 40 | 41 | func sha1digest(src string) string { //digest hex to sha1hex 42 | p, _ := hex.DecodeString(src) 43 | h := sha1.New() 44 | h.Write(p) 45 | s := h.Sum(nil) 46 | return strings.ToUpper(hex.EncodeToString(s)) 47 | } 48 | 49 | func makeCode(hash string, mep string) string { //creates unlock code 50 | var ( 51 | out = "" 52 | pos int 53 | size int 54 | ) 55 | 56 | const mep8digits = "MEP-23361-001,MEP-30218-002,MEP-15326-002,MEP-04626-002,MEP-27501-003,MEP-31845-001,MEP-22793-001,MEP-04103-001" 57 | pos = strings.Count(mep8digits, mep) 58 | bytes, err := hex.DecodeString(hash) 59 | if err != nil { 60 | panic(err) 61 | } 62 | if pos == 0 { 63 | size = 16 64 | } 65 | if pos != 0 { 66 | size = 8 67 | } 68 | for i := 0; i < size; i++ { 69 | preout := bytes[i] 70 | preout1 := strconv.FormatInt(int64(preout), 10) 71 | lenpreout := len(preout1) 72 | preout2 := preout1[lenpreout-1] 73 | out += string(preout2) 74 | } 75 | return out 76 | } 77 | 78 | func Blackberry(myMEP string, strIMEI string) string{ 79 | var ( 80 | out = "" 81 | inMEP [16]int 82 | ) 83 | if myMEP[0:3] == "MEP" { 84 | inMEP = findMEP(myMEP) 85 | } 86 | if myMEP[0:3] == "PRD" { 87 | inMEP = findPRD(myMEP) 88 | } 89 | for i := 1; i <= 5; i++ { 90 | precode := makeCode(makeSHA1(strIMEI, createPrivatePass(inMEP), i), myMEP) 91 | out+="MEP" + strconv.Itoa(i) + ":" + precode+"," 92 | } 93 | return out 94 | } 95 | -------------------------------------------------------------------------------- /ZTE.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "strconv" 6 | "fmt" 7 | "crypto/md5" 8 | "io" 9 | ) 10 | 11 | //ZTE SFR 114 12 | //ZTE SFR 231 13 | //ZTE SFR 232 14 | //ZTE SFR 241 15 | //ZTE SFR 251 16 | //ZTE SFR 251MSN 17 | //ZTE SFR 341 18 | //ZTE SFR 342 19 | //ZTE SFR 343 20 | //ZTE ORANGE Vegas 21 | //ZTE ORANGE MIAMI 22 | //ZTE VODAFONE INDIE 23 | //ZTE X760 24 | //ZTE X761 25 | //ZTE X960 26 | //ZTE GX760 27 | //ZTE GX761 28 | //ZTE A261+ 29 | //ZTE GR230 30 | //ZTE X990 31 | //ZTE T-Mobile Vairy Touch 32 | //ZTE N261 = N281 33 | //ZTE X990 34 | //ZTE X991 35 | //Orange Rio 36 | 37 | func zteOld(imei string) []string{ //zteB02? 38 | var ( 39 | magic = [12]int{6, 8, 8, 9, 5, 0, 0, 0, 0, 0, 0, 0} 40 | digits []int 41 | nck = "" 42 | spck = "" 43 | crosssum = 0 44 | ) 45 | for i,_ := range imei[3:15]{ 46 | imeiAsInt, err := strconv.Atoi(string(imei[i+3])) 47 | if err != nil{ 48 | panic(err) 49 | } 50 | digits = append(digits, imeiAsInt) 51 | } 52 | for i,_ := range digits{ 53 | crosssum += digits[i] 54 | } 55 | for i,_ := range(digits){ 56 | code := (digits[i]*crosssum + digits[11-i]*8 + magic[i]) % 10 57 | nck += strconv.Itoa(code) 58 | spck += strconv.Itoa((code + digits[11-i]) % 10) 59 | } 60 | return strings.Fields("NCK:"+nck + " SPCK:" + spck) 61 | } 62 | 63 | func zteB03(imei string) string { //zteB03 64 | var ( 65 | key [8]int64 66 | out = "" 67 | pre [16]int64 68 | err error 69 | ) 70 | mySum := md5.New() 71 | io.WriteString(mySum, imei) 72 | imeiMD5 := mySum.Sum(nil) 73 | for i,_ := range imeiMD5{ 74 | pre[i],err=strconv.ParseInt(fmt.Sprintf("%x", imeiMD5[i]),16,0) 75 | if err != nil{ 76 | panic(err) 77 | } 78 | } 79 | for i:=0; i <=7; i++{ 80 | key[i] = (((pre[i] + pre[i+8]) & int64(0xFF)*int64(0x09))/int64(0xFF)) 81 | out += fmt.Sprintf("%x", key[i]) 82 | } 83 | return "NCK:"+out 84 | } 85 | 86 | func zteB04(imei string) string { //zteB04 87 | var ( 88 | key [8]int64 89 | out = "" 90 | pre [16]int64 91 | err error 92 | ) 93 | mySum := md5.New() 94 | io.WriteString(mySum, imei) 95 | imeiMD5 := mySum.Sum(nil) 96 | for i,_ := range imeiMD5{ 97 | pre[i],err=strconv.ParseInt(fmt.Sprintf("%x", imeiMD5[i]),16,0) 98 | if err != nil{ 99 | panic(err) 100 | } 101 | } 102 | for i:=0; i <=7; i++{ 103 | key[i] = (((pre[i] + pre[i+8] + pre[i+4] + 40) & int64(0xFF)*int64(0x09))/int64(0xFF)) 104 | out += fmt.Sprintf("%x", key[i]) 105 | } 106 | return "NCK:"+out 107 | } 108 | -------------------------------------------------------------------------------- /Alcatel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "crypto/sha1" 6 | "io" 7 | "encoding/hex" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | func alcatelC700Calc(imei string, imp string, perm string, xorn string) string { //C700 & friends 13 | var ( 14 | swapimei = "08" //08 21 43 65 87 09 21 43 07 15 | permimei = "" //perm of swap 16 | doxor [20]int 17 | myxor byte 18 | pre = "" 19 | doswap [9]int 20 | err error 21 | tmpswap [9]string 22 | 23 | ) 24 | simei := imei + "0" 25 | for i:=0; i < (len(simei)-1); i++{ //swaps imei 26 | swapimei = swapimei + string(simei[i+1]) + string(simei[i]) 27 | i++ 28 | } 29 | for i:=0; i<(len(perm)-1); i++ { //sets up permimei 30 | doswap[i],err = strconv.Atoi(string(perm[i])) 31 | if err != nil{ 32 | panic(err) 33 | } 34 | } 35 | j:=0 36 | for i:=0; i<9; i++{ 37 | tmpswap[i] = string(swapimei[j]) + string(swapimei[j+1]) 38 | j = j + 2 39 | } 40 | for i:=0; i<(len(tmpswap)); i++{ //creates permimei 41 | permimei = permimei + string(tmpswap[(doswap[i])]) 42 | } 43 | presha1input := imp + swapimei + swapimei + permimei //forms sha1message 44 | sha1input,err := hex.DecodeString(presha1input) 45 | if err != nil{ 46 | panic(err) 47 | } 48 | digest := sha1.New() 49 | io.WriteString(digest,string(sha1input)) 50 | hexStr := fmt.Sprintf("%x",digest.Sum(nil)) 51 | bRay,err := hex.DecodeString(string(hexStr)) 52 | if err != nil{ 53 | panic(err) 54 | } 55 | xorder,err := hex.DecodeString(xorn) //parses xorder 56 | if err != nil{ 57 | panic(err) 58 | } 59 | for i := 0; i < (len(xorder)-1); i++{ //makes []int of xorder 60 | doxor[i],err = strconv.Atoi(fmt.Sprintf("%d",xorder[i])) 61 | if err != nil{ 62 | panic(err) 63 | } 64 | } 65 | for i:= 0; i < (len(doxor)-1); i++{ //xors bytes 66 | myxor = bRay[(doxor[i])] ^ bRay[(doxor[i+1])] ^ bRay[(doxor[i+2])] ^ bRay[(doxor[i+3])] ^ bRay[(doxor[i+4])] 67 | pre += fmt.Sprintf("%02x", myxor) //hex encodes bytes to string 68 | i = i+4 69 | } 70 | out,err := strconv.ParseInt(pre,16,64) //parses hexstring to base 10 code 71 | if err != nil { 72 | panic(err) 73 | } 74 | return fmt.Sprintf("%d",out) //makes code a string 75 | } 76 | 77 | func alcatelC700(model string, imei string) []string { 78 | var ( 79 | modata = map[string][]string{ 80 | "duck":[]string{"8F", "BE", "876543210", "110A090201100B0803000F0C0704130E0D060512"}, //MANDARINA DUCK | C820 | C825 81 | "playboy":[]string{"3C", "E2", "785432106", "0B121307000C110806010D100905020E0F0A0403"}, //C717 | C700 | C701 | EL03 | PLAYBOY 82 | "misssixty":[]string{"6C", "B9", "456132807", "0503011311040200121007090B0D0F06080A0C0E"}, //MISSSIXTY | S520 83 | "s215":[]string{"74", "9A", "547682031", "0504010D0F0C06070A0010080B0E031202111309"}, //S215 | S218 | S219 | S320 | S321 84 | "s853":[]string{"53", "AE", "876543210", "0004080C100105090D1102060A0E1203070B0F13"}} //S853 !!!PERM UNKNOWN!!! 85 | modeldb = map[string][]string{ 86 | "MandarinaDuck":modata["duck"], 87 | "C820":modata["duck"], 88 | "C825":modata["duck"], 89 | "Playboy":modata["playboy"], 90 | "C717":modata["playboy"], 91 | "C700":modata["playboy"], 92 | "EL03":modata["playboy"], 93 | "MissSixty":modata["misssixty"], 94 | "S520":modata["misssixty"], 95 | "S215":modata["s215"], 96 | "S218":modata["s215"], 97 | "S219":modata["s215"], 98 | "S320":modata["s215"], 99 | "S321":modata["s215"], 100 | "S853":modata["duck"]} 101 | ) 102 | whichmodel := modeldb[model] 103 | return strings.Fields("NCK:"+ alcatelC700Calc(imei,whichmodel[0],whichmodel[2], whichmodel[3]) + " SPCK:" + alcatelC700Calc(imei,whichmodel[1],whichmodel[2], whichmodel[3])) 104 | } 105 | --------------------------------------------------------------------------------