This repository has been archived by the owner on Sep 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathmg-mlb-serial
executable file
·170 lines (152 loc) · 5.75 KB
/
mg-mlb-serial
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env bash
# mg-mlb-serial - Mac MLB serial number generator
# The repo folder
gRepo=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=mg-common
source "$gRepo/mg-common"
function help()
{
echo "mg-mlb-serial v$gScriptVersion"
echo "Mac MLB serial number generator script"
echo
echo "Usage: mg-mlb-serial <product name> <serial number>"
echo
echo " <product name> Target Mac product name (model ID)"
echo " <serial number> Target Mac system serial number"
echo " --help (-h) Help (this screen)"
echo
echo "If no values are specified, system values from the IORegistry will be used."
exit 0
}
function print_serial_number()
{
printf "\n "
local serialPPP="${gSerialNumber:0:3}"
local serialY="${gSerialNumber:3:1}"
local serialW="${gSerialNumber:4:1}"
local serialSSS="${gSerialNumber:5:3}"
local serialCCCC="${gSerialNumber:8:4}"
printf "%b%b%s %b%s %b%s %b%b%s %b%s%b\n" $gStyleBold $gColorGreen "$serialPPP" \
$gColorRed "$serialY" $gColorBlue "$serialW" $gStyleReset $gStyleBold "$serialSSS" \
$gColorPurple "$serialCCCC" $gStyleReset
}
function generate_mlb_serial()
{
# Source existing model data
if [[ "$gProductName" =~ "iMac" ]]; then
# shellcheck source=data/iMac.dat
source "$gRepo/data/iMac.dat"
elif [[ "$gProductName" =~ "MacBookAir" ]]; then
# shellcheck source=data/MacBookAir.dat
source "$gRepo/data/MacBookAir.dat"
elif [[ "$gProductName" =~ "MacBookPro" ]]; then
# shellcheck source=data/MacBookPro.dat
source "$gRepo/data/MacBookPro.dat"
elif [[ "$gProductName" =~ "MacBook" ]]; then
# shellcheck source=data/MacBook.dat
source "$gRepo/data/MacBook.dat"
elif [[ "$gProductName" =~ "Macmini" ]]; then
# shellcheck source=data/Macmini.dat
source "$gRepo/data/Macmini.dat"
elif [[ "$gProductName" =~ "MacPro" ]]; then
# shellcheck source=data/MacPro.dat
source "$gRepo/data/MacPro.dat"
else
print_error "Invalid model identifier!"
fi
# Get the manufacturing location from the serial number
local PPP="${gSerialNumber:0:3}"
if [ $gDebug -eq 1 ]; then
local location=$(decode_location_val "$PPP")
print_debug "Manufacturing location (from serial number)" "$location"
fi
# Get the Y value (manufacturing year) from the serial number
local serialY="${gSerialNumber:3:1}"
# Decode the serial number Y value to get the MLB Y value
Y=$(decode_year_val "$serialY")
if [ $gDebug -eq 1 ]; then
print_debug "Manufacturing year (from serial number)" "201$Y"
fi
# Make sure the year value is valid (within the expected range)
# Credit: https://stackoverflow.com/a/8574392
# local e
# if [[ $(for e in "${YCodes[@]}"; do [[ "$e" == "$serialY" ]] && echo 0; done) != "0" ]]; then
# Y value from serial number does not match the expected range in the model data.
# Exit and print error message
# print_serial_number
# printf " ^\n"
# print_error "Invalid year in serial number ($gProductName was not produced in 201$Y)!"
# fi
# Get the WW value (manufacturing week) from the serial number
local serialW="${gSerialNumber:4:1}"
# Decode the serial number W value to get the MLB WW value
## Logic boards are produced ~1 week before the system is complete
local WW=$(($(decode_week_val "$serialY" "$serialW") - 1))
if [ $gDebug -eq 1 ]; then
print_debug "Manufacturing week (from serial number)" "$WW"
fi
# Make sure the week value is valid
if [ "$WW" -lt 0 ]; then
# Week number value is less than zero. Exit and print error message.
print_serial_number
printf " ^\n"
print_error "Invalid week in serial number ($WW is less than zero)!"
fi
# Get the TTT value (board type) from the model data
local TTT="$boardType"
if [ $gDebug -eq 1 ]; then
print_debug "Generated board type" "$TTT"
fi
# Generate the CC value (checksum?)
# TODO: Research if this is a checksum, and see if it is possible to calculate it from the ROM
local CCCodes=('GU' '4N' 'J9' 'QX' 'OP' 'CD' '3F' 'U5' 'KP' 'D5' 'SJ' '7P' 'RG' 'W5' '92' 'MA' '2Y' '26' 'L0' 'NA' 'TL' '2D' '8U')
local CCIndex=$(jot -r 1 0 $((${#CCCodes[@]} - 1)))
local CC=${CCCodes[CCIndex]}
if [ $gDebug -eq 1 ]; then
print_debug "Generated CC value" "$CC"
fi
# Generate the EEEE value from the model data
local EEEEIndex=$(jot -r 1 0 $((${#EEEECodes[@]} - 1)))
local EEEE=${EEEECodes[EEEEIndex]}
if [ $gDebug -eq 1 ]; then
print_debug "Generated EEEE value" "$EEEE"
fi
# Generate the KK value
# TODO: Research this
local KKCodes=('1H' '1M' 'AD' '1F' 'A8' 'UE' 'JA' 'JC' '8C' 'CB' 'FB' 'A6' 'AL' 'AN' '16' 'A5' 'AH' 'AA' 'AD' 'AK' 'AN' '1W' 'AY' '1A')
local KKIndex=$(jot -r 1 0 $((${#KKCodes[@]} - 1)))
local KK=${KKCodes[KKIndex]}
if [ $gDebug -eq 1 ]; then
print_debug "Generated KK value" "$KK"
fi
gMLBSerialNumber="$PPP$Y$WW$TTT$CC$EEEE$KK"
}
# How many arguments were supplied?
if [ $# -eq 1 ]; then
# Not enough. Print help and exit
help
exit
elif [ $# -eq 2 ]; then
# Two. Set gProductName and gSerialNumber to the supplied parameters
gProductName="$1"
gSerialNumber="$2"
else
# None. Use the system model ID and system serial number (from the IORegistry)
gProductName=$(ioreg -k product-name -d 2 | awk '/product-name/ {print $3}' | tr -d '"<>')
gSerialNumber=$(ioreg -k IOPlatformSerialNumber -d 2 | awk '/IOPlatformSerialNumber/ {print $3}' | tr -d '"')
if [ $gDebug -eq 1 ]; then
print_debug "NOTE" "No input product name found, using IORegistry value ($gProductName)"
print_debug "NOTE" "No input serial number found, using IORegistry value ($gSerialNumber)"
fi
fi
# Verify that serial number is 12 characters
if [ ${#gSerialNumber} -ne 12 ]; then
print_error "Invalid serial number (not 12 characters)!"
fi
generate_mlb_serial
if [ $gDebug -eq 1 ]; then
echo
print_debug "Generated $gProductName MLB serial number" "$gMLBSerialNumber"
else
echo "$gMLBSerialNumber"
fi