Wi-Fi மற்றும் பல சுருக்கங்கள். வீக்கமடையாமல் ஆண்ட்ராய்டு பயன்பாட்டில் வைஃபை நோட்களைப் பற்றிய தரவைப் பெறுவது எப்படி

ஒரு நாள் ஆண்ட்ராய்டு அப்ளிகேஷன்களில் இருந்து வைஃபை நெட்வொர்க்குகளை ஸ்கேன் செய்து அணுகல் புள்ளிகள் பற்றிய விரிவான தரவைப் பெற வேண்டியிருந்தது.

இங்கே நாங்கள் பல சிரமங்களை எதிர்கொள்ள வேண்டியிருந்தது: ஆஃப்.ஆண்ட்ராய்டு ஆவணங்கள் விவரிக்கப்பட்ட பல வகுப்புகள் நிராகரிக்கப்பட்டன (API நிலை > 26), இது அதில் பிரதிபலிக்கவில்லை; ஆவணத்தில் சில விஷயங்களின் விளக்கம் குறைவாக உள்ளது (எடுத்துக்காட்டாக, வகுப்பின் திறன்கள் புலம் ஸ்கேன் முடிவு எழுதும் நேரத்தில், கிட்டத்தட்ட எதுவும் விவரிக்கப்படவில்லை, இருப்பினும் அதில் நிறைய முக்கியமான தரவுகள் உள்ளன). மூன்றாவது சிரமம் என்னவென்றால், நீங்கள் முதலில் Wi-Fi ஐ நெருங்கும்போது, ​​கோட்பாட்டைப் படித்து லோக்கல் ஹோஸ்ட் வழியாக ரூட்டரை அமைப்பதைத் தவிர, தனித்தனியாக புரிந்துகொள்ளக்கூடிய பல சுருக்கங்களை நீங்கள் கையாள வேண்டும். ஆனால் அவற்றை எவ்வாறு தொடர்புபடுத்துவது மற்றும் கட்டமைப்பது என்பது வெளிப்படையாக இருக்காது (தீர்ப்பு என்பது அகநிலை மற்றும் முந்தைய அனுபவத்தைப் பொறுத்தது).

என்டிகே, ஹேக்குகள் இல்லாமல் ஆண்ட்ராய்டு குறியீட்டிலிருந்து வைஃபை சூழலைப் பற்றிய விரிவான தரவை எப்படிப் பெறுவது, ஆனால் ஆண்ட்ராய்டு ஏபிஐ மட்டும் பயன்படுத்தி அதை எப்படி விளக்குவது என்பதைப் பற்றி இந்தக் கட்டுரை விவாதிக்கிறது.

தாமதிக்காமல் குறியீடு எழுதத் தொடங்குவோம்.

1. ஒரு திட்டத்தை உருவாக்கவும்

இந்தக் குறிப்பு ஒன்றுக்கு மேற்பட்ட முறை Android திட்டத்தை உருவாக்கியவர்களுக்காக வடிவமைக்கப்பட்டுள்ளது, எனவே இந்த உருப்படியின் விவரங்களை நாங்கள் தவிர்க்கிறோம். கீழே உள்ள குறியீடு Kotlin, minSdkVersion=23 இல் வழங்கப்படும்.

2. அணுகல் அனுமதிகள்

பயன்பாட்டிலிருந்து Wi-Fi உடன் பணிபுரிய, நீங்கள் பயனரிடமிருந்து பல அனுமதிகளைப் பெற வேண்டும். அதற்கு ஏற்ப ஆவணங்கள், 8.0 க்குப் பிறகு OS பதிப்புகளைக் கொண்ட சாதனங்களில் நெட்வொர்க்கை ஸ்கேன் செய்ய, நெட்வொர்க் சூழலின் நிலையைப் பார்ப்பதற்கு கூடுதலாக, சாதனத்தின் Wi-Fi தொகுதியின் நிலையை மாற்றுவதற்கான அணுகல் அல்லது ஒருங்கிணைப்புகளுக்கான அணுகல் (தோராயமான) அல்லது சரியானது). பதிப்பு 9.0 இல் தொடங்கி, இரண்டிற்கும் பயனரை நீங்கள் கேட்க வேண்டும், மேலும் இருப்பிடச் சேவைகளை இயக்குமாறு பயனரை வெளிப்படையாகக் கோர வேண்டும். இது கூகுளின் விருப்பமே தவிர, அவரை உளவு பார்ப்பது எங்கள் விருப்பம் அல்ல என்பதை பயனருக்கு தைரியமாக விளக்க மறக்காதீர்கள் :)

எனவே, AndroidManifest.xml இல் நாம் சேர்ப்போம்:

    <uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android_name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android_name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android_name="android.permission.ACCESS_FINE_LOCATION"/>

தற்போதைய செயல்பாட்டிற்கான இணைப்பைக் கொண்டிருக்கும் குறியீட்டில்:

import android.app.Activity
import android.content.Context
import android.location.LocationManager
import androidx.core.app.ActivityCompat

....

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE),
                1
            )
            makeEnableLocationServices(activity.applicationContext)
        } else {
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(Manifest.permission.CHANGE_WIFI_STATE),
                1
            )
        }

    /* включает экран включения службы по определению местоположения */
    fun makeEnableLocationServices(context: Context) {
        // TODO: перед вызовом этой функции надо рассказать пользователю, зачем Вам доступ к местоположению
        val lm: LocationManager =
            context.applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager

        val gpsEnabled: Boolean = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        val networkEnabled: Boolean = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!gpsEnabled && !networkEnabled) {
            context.startActivity(Intent(ACTION_LOCATION_SOURCE_SETTINGS));
        }
    }

3. பிராட்காஸ்ட் ரிசீவரை உருவாக்கி, வைஃபை நெட்வொர்க் சூழலை ஸ்கேன் செய்வது பற்றிய தரவு புதுப்பிப்பு நிகழ்வுகளுக்கு குழுசேரவும்

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

val wifiScanReceiver = object : BroadcastReceiver() {

  override fun onReceive(context: Context, intent: Intent) {
    val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
    if (success) {
      scanSuccess()
    } 
  }
}

val intentFilter = IntentFilter()
/* подписываемся на сообщения о получении новых результатов сканирования */
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)

val success = wifiManager.startScan()
if (!success) {
  /* что-то не получилось при запуске сканирования, проверьте выданые разрешения */
}

....

private fun scanSuccess() {
 /* вот они, результаты сканирования */
  val results: List<ScanResult> = wifiManager.scanResults
}

ஆவணத்தில் WiFiManager.startScan முறையானது API பதிப்பு 28 இல் இருந்து நீக்கப்பட்டதாகக் குறிக்கப்பட்டுள்ளது, ஆனால் முடக்கப்பட்டுள்ளது. வழிகாட்டும் பயன்படுத்த பரிந்துரைக்கிறது.

மொத்தத்தில், பொருட்களின் பட்டியலைப் பெற்றோம் ஸ்கேன் முடிவு.

4. ஸ்கேன் ரிசல்ட்டைப் பார்த்து, விதிமுறைகளைப் புரிந்து கொள்ளுங்கள்

இந்த வகுப்பின் சில துறைகளைப் பார்த்து, அவை எதைக் குறிக்கின்றன என்பதை விவரிப்போம்:

SSID உடன் — சர்வீஸ் செட் ஐடென்டிஃபையர் என்பது நெட்வொர்க்கின் பெயர்

பி.எஸ்.எஸ்.ஐ.டி – அடிப்படை சேவை அமைப்பு அடையாளங்காட்டி – பிணைய அடாப்டரின் MAC முகவரி (வைஃபை புள்ளி)

நிலை - பெறப்பட்ட சிக்னல் வலிமை காட்டி [dBm (ரஷியன் dBm) - டெசிபல், குறிப்பு சக்தி 1 மெகாவாட்.] - பெறப்பட்ட சமிக்ஞை வலிமையின் குறிகாட்டி. 0 முதல் -100 வரையிலான மதிப்பை எடுக்கும், 0 இலிருந்து மேலும், உங்கள் சாதனத்திற்கு Wi-Fi புள்ளியிலிருந்து அதிக சமிக்ஞை சக்தி இழக்கப்படும். மேலும் விவரங்களைக் காணலாம், எடுத்துக்காட்டாக, இல் விக்கிப்பீடியா. ஆண்ட்ராய்டு வகுப்பைப் பயன்படுத்துவதை இங்கே நான் உங்களுக்குச் சொல்கிறேன் வைஃபைமேனேஜர் நீங்கள் தேர்ந்தெடுக்கும் படியில் சிக்னல் அளவை சிறப்பானது முதல் பயங்கரமானது வரை அளவீடு செய்யலாம்:

        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val numberOfLevels = 5
        val level = WifiManager.calculateSignalLevel(level, numberOfLevels)

அதிர்வெண் - Wi-Fi புள்ளியின் இயக்க அதிர்வெண் [Hz]. அலைவரிசைக்கு கூடுதலாக, சேனல் என்று அழைக்கப்படுவதில் நீங்கள் ஆர்வமாக இருக்கலாம். ஒவ்வொரு புள்ளிக்கும் அதன் சொந்த இயக்க தூய்மை உள்ளது. எழுதும் நேரத்தில், Wi-Fi புள்ளிகளின் மிகவும் பிரபலமான வரம்பு 2.4 GHz ஆகும். ஆனால், இன்னும் துல்லியமாகச் சொல்வதானால், புள்ளியானது பெயரிடப்பட்ட அதிர்வெண்ணுக்கு நெருக்கமான எண்ணிடப்பட்ட அதிர்வெண்ணில் உங்கள் ஃபோனுக்கு தகவலை அனுப்புகிறது. சேனல்களின் எண்ணிக்கை மற்றும் தொடர்புடைய அதிர்வெண்கள் தரப்படுத்தப்பட்டது. அருகிலுள்ள புள்ளிகள் வெவ்வேறு அதிர்வெண்களில் செயல்படும் வகையில் இது செய்யப்படுகிறது, இதன் மூலம் ஒருவருக்கொருவர் தலையிடாது மற்றும் பரிமாற்றத்தின் வேகத்தையும் தரத்தையும் பரஸ்பரம் குறைக்காது. இந்த வழக்கில், புள்ளிகள் ஒரு அதிர்வெண்ணில் இயங்கவில்லை, ஆனால் அதிர்வெண்களின் வரம்பில் (அளவுரு சேனல்அகலம்), சேனல் அகலம் என்று அழைக்கப்படுகிறது. அதாவது, அருகிலுள்ள (மற்றும் அருகிலுள்ளது மட்டுமல்ல, தங்களிடமிருந்து 3) சேனல்களில் செயல்படும் புள்ளிகள் ஒருவருக்கொருவர் தலையிடுகின்றன. இந்த எளிய குறியீடு உங்களுக்கு பயனுள்ளதாக இருக்கும், இது 2.4 மற்றும் 5 Ghz அதிர்வெண் கொண்ட புள்ளிகளுக்கான அலைவரிசை மதிப்பிலிருந்து சேனல் எண்ணைக் கணக்கிட உங்களை அனுமதிக்கிறது:


    /* по частоте определяем номер канала */
    val channel: Int
        get() {
            return if (frequency in 2412..2484) {
                (frequency - 2412) / 5 + 1
            } else if (frequency in 5170..5825) {
                (frequency - 5170) / 5 + 34
            } else {
                -1
            }
        }

திறன்களை - பகுப்பாய்விற்கான மிகவும் சுவாரஸ்யமான புலம், நிறைய நேரம் தேவைப்படும் வேலை. இங்கே புள்ளியின் "திறன்கள்" வரியில் எழுதப்பட்டுள்ளன. இந்த வழக்கில், ஆவணத்தில் சரம் விளக்கத்தின் விவரங்களை நீங்கள் பார்க்க வேண்டியதில்லை. இந்த வரியில் என்ன இருக்கலாம் என்பதற்கான சில எடுத்துக்காட்டுகள் இங்கே:

[WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS]
[WPA2-PSK-CCMP][ESS]
[WPA2-PSK-CCMP+TKIP][ESS]
[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS]
[ESS][WPS]

5. சுருக்கங்கள் மற்றும் பாகுபடுத்தும் திறன்களைப் புரிந்துகொள்வது

android.net.wifi.* தொகுப்பின் வகுப்புகள் லினக்ஸ் பயன்பாட்டால் ஹூட்டின் கீழ் பயன்படுத்தப்படுகின்றன என்பது குறிப்பிடத் தக்கது. wpa_விண்ணப்பதாரர் மற்றும் திறன்கள் துறையில் வெளியீடு விளைவாக ஸ்கேன் செய்யும் போது கொடிகள் துறையில் ஒரு நகல் உள்ளது.

தொடர்ந்து செயல்படுவோம். அடைப்புக்குறிக்குள் உள்ள கூறுகள் “-“ அடையாளத்தால் பிரிக்கப்படும் வடிவமைப்பின் வெளியீட்டை முதலில் கருத்தில் கொள்வோம்:

[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]

முதல் பொருள் என்று அழைக்கப்படுவதை விவரிக்கிறது. அங்கீகார முறை. அதாவது, அணுகல் புள்ளியைப் பயன்படுத்துவதற்கும், பேலோடை எவ்வாறு குறியாக்கம் செய்வது என்பதற்கும் சாதனமும் அணுகல் புள்ளியும் என்ன வரிசை செயல்களைச் செய்ய வேண்டும். இந்த இடுகையை எழுதும் நேரத்தில், மிகவும் பொதுவான விருப்பங்கள் WPA மற்றும் WPA2 ஆகும், இதில் இணைக்கப்பட்ட ஒவ்வொரு சாதனமும் நேரடியாகவோ அல்லது அழைக்கப்படும் மூலமாகவோ இருக்கும். RADIUS சேவையகம் (WPA-Enterprice) ஒரு மறைகுறியாக்கப்பட்ட சேனலில் கடவுச்சொல்லை வழங்குகிறது. பெரும்பாலும், உங்கள் வீட்டில் உள்ள அணுகல் புள்ளி இந்த திட்டத்தின் படி இணைப்பை வழங்குகிறது. இரண்டாவது பதிப்பிற்கும் முதல் பதிப்பிற்கும் உள்ள வித்தியாசம் என்னவென்றால், இது ஒரு வலுவான மறைக்குறியீட்டைக் கொண்டுள்ளது: AES மற்றும் பாதுகாப்பற்ற TKIP. மிகவும் சிக்கலான மற்றும் மேம்பட்ட WPA3, படிப்படியாக அறிமுகப்படுத்தப்படுகிறது. கோட்பாட்டளவில், நிறுவன தீர்வு CCKM (சிஸ்கோ மையப்படுத்தப்பட்ட விசை மேலாண்மை) உடன் ஒரு விருப்பம் இருக்கலாம், ஆனால் நான் அதை ஒருபோதும் காணவில்லை.

MAC முகவரி மூலம் அங்கீகரிக்க அணுகல் புள்ளி கட்டமைக்கப்பட்டிருக்கலாம். அல்லது, அணுகல் புள்ளியானது காலாவதியான WEP அல்காரிதத்தைப் பயன்படுத்தி தரவை வழங்கினால், உண்மையில் அங்கீகாரம் இல்லை (இங்கே உள்ள ரகசிய விசை குறியாக்க விசையாகும்). அத்தகைய விருப்பங்களை நாங்கள் OTHER என வகைப்படுத்துகிறோம்.
மறைக்கப்பட்ட கேப்டிவ் போர்டல் கண்டறிதலுடன் பொது வைஃபையில் பிரபலமான ஒரு முறையும் உள்ளது - உலாவி மூலம் அங்கீகார கோரிக்கை. அத்தகைய அணுகல் புள்ளிகள் ஸ்கேனருக்கு திறந்ததாகத் தோன்றும் (அவை இயற்பியல் இணைப்பின் பார்வையில் உள்ளன). எனவே, நாங்கள் அவற்றை OPEN என வகைப்படுத்துகிறோம்.

இரண்டாவது மதிப்பை இவ்வாறு குறிப்பிடலாம் முக்கிய மேலாண்மை அல்காரிதம். இது மேலே விவரிக்கப்பட்ட அங்கீகார முறையின் அளவுருவாகும். குறியாக்க விசைகள் எவ்வாறு சரியாக பரிமாறப்படுகின்றன என்பதைப் பற்றி பேசுகிறது. சாத்தியமான விருப்பங்களைக் கருத்தில் கொள்வோம். EAP - குறிப்பிடப்பட்ட WPA-Enterprice இல் பயன்படுத்தப்படுகிறது, உள்ளிட்ட அங்கீகாரத் தரவைச் சரிபார்க்க தரவுத்தளத்தைப் பயன்படுத்துகிறது. SAE - மேம்பட்ட WPA3 இல் பயன்படுத்தப்பட்டது, முரட்டு சக்திக்கு அதிக எதிர்ப்பு. PSK - மிகவும் பொதுவான விருப்பம், கடவுச்சொல்லை உள்ளிட்டு அதை மறைகுறியாக்கப்பட்ட வடிவத்தில் அனுப்புகிறது. IEEE8021X - சர்வதேச தரநிலையின்படி (WPA குடும்பத்தால் ஆதரிக்கப்படுவதிலிருந்து வேறுபட்டது). OWE (Opportunistic Wireless Encryption) என்பது நாம் OPEN என வகைப்படுத்திய புள்ளிகளுக்கான IEEE 802.11 தரநிலையின் நீட்டிப்பாகும். OWE ஆனது பாதுகாப்பற்ற நெட்வொர்க்கில் அனுப்பப்படும் தரவின் பாதுகாப்பை என்கிரிப்ட் செய்வதன் மூலம் உறுதி செய்கிறது. அணுகல் விசைகள் இல்லாதபோது ஒரு விருப்பமும் சாத்தியமாகும், இந்த விருப்பத்தை NONE என்று அழைப்போம்.

மூன்றாவது அளவுரு என்று அழைக்கப்படுகிறது. குறியாக்க திட்டங்கள் — கடத்தப்பட்ட தரவைப் பாதுகாக்க மறைக்குறியீடு எவ்வாறு சரியாகப் பயன்படுத்தப்படுகிறது. விருப்பங்களை பட்டியலிடுவோம். WEP - ஒரு RC4 ஸ்ட்ரீம் மறைக்குறியீட்டைப் பயன்படுத்துகிறது, இரகசிய விசை குறியாக்க விசையாகும், இது நவீன குறியாக்க உலகில் ஏற்றுக்கொள்ள முடியாததாகக் கருதப்படுகிறது. TKIP - WPA இல் பயன்படுத்தப்படுகிறது, CKIP - WPA2 இல். TKIP+CKIP - பின்தங்கிய இணக்கத்தன்மைக்கு WPA மற்றும் WPA2 திறன் கொண்ட புள்ளிகளில் குறிப்பிடலாம்.

மூன்று கூறுகளுக்குப் பதிலாக, நீங்கள் தனிமையான WEP குறியைக் காணலாம்:

[WEP]

நாம் மேலே விவாதித்தபடி, விசைகளைப் பயன்படுத்துவதற்கான வழிமுறையைக் குறிப்பிடாமல் இருப்பதற்கு இது போதுமானது, இது இல்லாதது, மற்றும் முன்னிருப்பாக இருக்கும் குறியாக்க முறை.

இப்போது இந்த அடைப்புக்குறியைக் கவனியுங்கள்:

[ESS]

இந்த வைஃபை இயக்க முறை அல்லது வைஃபை நெட்வொர்க் டோபாலஜி. நீங்கள் BSS (அடிப்படை சேவை தொகுப்பு) பயன்முறையை சந்திக்கலாம் - இணைக்கப்பட்ட சாதனங்கள் தொடர்பு கொள்ளும் அணுகல் புள்ளி இருக்கும் போது. உள்ளூர் நெட்வொர்க்குகளில் காணலாம். ஒரு விதியாக, வெவ்வேறு உள்ளூர் நெட்வொர்க்குகளிலிருந்து சாதனங்களை இணைக்க அணுகல் புள்ளிகள் தேவைப்படுகின்றன, எனவே அவை விரிவாக்கப்பட்ட சேவை தொகுப்புகளின் பகுதியாகும் - ESS. IBSSs (Independent Basic Service Sets) வகையானது சாதனமானது பியர்-டு-பியர் நெட்வொர்க்கின் ஒரு பகுதியாக இருப்பதைக் குறிக்கிறது.

நீங்கள் WPS கொடியையும் பார்க்கலாம்:

[WPS]

WPS (Wi-Fi பாதுகாக்கப்பட்ட அமைப்பு) என்பது Wi-Fi நெட்வொர்க்கின் அரை தானியங்கி துவக்கத்திற்கான ஒரு நெறிமுறை ஆகும். துவக்க, பயனர் 8-எழுத்துகள் கொண்ட கடவுச்சொல்லை உள்ளிடுவார் அல்லது ரூட்டரில் ஒரு பொத்தானை அழுத்தவும். உங்கள் அணுகல் புள்ளி முதல் வகையாக இருந்தால், உங்கள் அணுகல் புள்ளியின் பெயருக்கு அடுத்ததாக இந்த தேர்வுப்பெட்டி தோன்றினால், நிர்வாகி குழுவிற்குச் சென்று WPS அணுகலை முடக்குமாறு நீங்கள் கடுமையாகப் பரிந்துரைக்கப்படுகிறீர்கள். உண்மை என்னவென்றால், பெரும்பாலும் 8-இலக்க பின்னை MAC முகவரி மூலம் கண்டறியலாம் அல்லது அதை யாரோ நேர்மையற்ற முறையில் பயன்படுத்திக் கொள்ளக்கூடிய நேரத்தில் அதை வரிசைப்படுத்தலாம்.

6. மாதிரி மற்றும் பாகுபடுத்தும் செயல்பாட்டை உருவாக்கவும்

மேலே நாம் கண்டறிந்தவற்றின் அடிப்படையில், தரவு வகுப்புகளைப் பயன்படுத்தி என்ன நடந்தது என்பதை விவரிப்போம்:

/* схема аутентификации */
enum class AuthMethod {
    WPA3,
    WPA2,
    WPA, // Wi-Fi Protected Access
    OTHER, // включает в себя Shared Key Authentication и др. использующие mac-address-based и WEP
    CCKM, // Cisco
    OPEN // Open Authentication. Может быть со скрытым Captive Portal Detection - запрос аутентификации через браузер
}

/* алгоритм ввода ключей */
enum class KeyManagementAlgorithm {
    IEEE8021X, // по стандарту
    EAP, // Extensible Authentication Protocol, расширяемый протокол аутентификации
    PSK, // Pre-Shared Key — каждый узел вводит пароль для доступа к сети
    WEP, // в WEP пароль является ключом шифрования (No auth key)
    SAE, // Simultaneous Authentication of Equals - может быть в WPA3
    OWE, // Opportunistic Wireless Encryption - в роутерах новых поколений, публичных сетях типа OPEN
    NONE // может быть без шифрования в OPEN, OTHER
}

/* метод шифрования */
enum class CipherMethod {
    WEP, // Wired Equivalent Privacy, Аналог шифрования трафика в проводных сетях
    TKIP, // Temporal Key Integrity Protocol
    CCMP, // Counter Mode with Cipher Block Chaining Message Authentication Code Protocol,
    // протокол блочного шифрования с кодом аутентичности сообщения и режимом сцепления блоков и счетчика
    // на основе AES
    NONE // может быть без шифрования в OPEN, OTHER
}

/* набор методов шифрования и протоколов, по которым может работать точка */
data class Capability(
    var authScheme: AuthMethod? = null,
    var keyManagementAlgorithm: KeyManagementAlgorithm? = null,
    var cipherMethod: CipherMethod? = null
)

/* Режим работы WiFi (или топология сетей WiFi) */
enum class TopologyMode {
    IBSS, // Эпизодическая сеть (Ad-Hoc или IBSS – Independent Basic Service Set).
    BSS, // Основная зона обслуживания Basic Service Set (BSS) или Infrastructure Mode.
    ESS // Расширенная зона обслуживания ESS – Extended Service Set.
}

இப்போது திறன் புலத்தை அலசும் ஒரு செயல்பாட்டை எழுதுவோம்:


private fun parseCapabilities(capabilitiesString: String): List < Capability > {
    val capabilities: List < Capability > = capabilitiesString
        .splitByBrackets()
        .filter {
            !it.isTopology() && !it.isWps()
        }
        .flatMap {
            parseCapability(it)
        }
    return
        if (!capabilities.isEmpty()) {
            capabilities
        } else {
            listOf(Capability(AuthMethod.OPEN, KeyManagementAlgorithm.NONE, CipherMethod.NONE))
        }
}

private fun parseCapability(part: String): List < Capability > {
    if (part.contains("WEP")) {
        return listOf(Capability(
            AuthMethod.OTHER,
            KeyManagementAlgorithm.WEP,
            CipherMethod.WEP
        ))
    }

    val authScheme = when {
        part.contains("WPA3") - > AuthMethod.WPA3
        part.contains("WPA2") - > AuthMethod.WPA2
        part.contains("WPA") - > AuthMethod.WPA
        else - > null
    }

    val keyManagementAlgorithm = when {
        part.contains("OWE") - > KeyManagementAlgorithm.OWE
        part.contains("SAE") - > KeyManagementAlgorithm.SAE
        part.contains("IEEE802.1X") - > KeyManagementAlgorithm.IEEE8021X
        part.contains("EAP") - > KeyManagementAlgorithm.EAP
        part.contains("PSK") - > KeyManagementAlgorithm.PSK
        else - > null
    }

    val capabilities = ArrayList < Capability > ()
    if (part.contains("TKIP") || part.contains("CCMP")) {
        if (part.contains("TKIP")) {
            capabilities.add(Capability(
                authScheme ? : AuthMethod.OPEN,
                keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
                CipherMethod.TKIP
            ))
        }
        if (part.contains("CCMP")) {
            capabilities.add(Capability(
                authScheme ? : AuthMethod.OPEN,
                keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
                CipherMethod.CCMP
            ))
        }
    } else if (authScheme != null || keyManagementAlgorithm != null) {
        capabilities.add(Capability(
            authScheme ? : AuthMethod.OPEN,
            keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
            CipherMethod.NONE
        ))
    }

    return capabilities
}

private fun parseTopologyMode(capabilitiesString: String): TopologyMode ? {
    return capabilitiesString
        .splitByBrackets()
        .mapNotNull {
            when {
                it.contains("ESS") - > TopologyMode.ESS
                it.contains("BSS") - > TopologyMode.BSS
                it.contains("IBSS") - > TopologyMode.IBSS
                else - > null
            }
        }
        .firstOrNull()
}

private fun parseWPSAvailable(capabilitiesString: String): Boolean {
    return capabilitiesString
        .splitByBrackets()
        .any {
            it.isWps()
        }
}

private fun String.splitByBrackets(): List < String > {
    val m = Pattern.compile("[(.*?)]").matcher(this)
    val parts = ArrayList < String > ()
    while (m.find()) {
        parts.add(m.group().replace("[", "").replace("]", ""))
    }
    return parts
}

private fun String.isTopology(): Boolean {
    return TopologyMode.values().any {
        this == it.name
    }
}

private fun String.isWps(): Boolean {
    return this == "WPS"
}

8. முடிவைப் பார்க்கவும்

நெட்வொர்க்கை ஸ்கேன் செய்து நான் கண்டுபிடித்ததை உங்களுக்குக் காட்டுகிறேன். Log.d வழியாக எளிய வெளியீட்டின் முடிவுகள் காட்டப்பட்டுள்ளன:

Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true

பயன்பாட்டுக் குறியீட்டிலிருந்து பிணையத்துடன் இணைப்பதில் உள்ள சிக்கல் ஆராயப்படவில்லை. மொபைல் சாதனத்தின் OS இலிருந்து சேமிக்கப்பட்ட கடவுச்சொற்களைப் படிக்க, உங்களுக்கு ரூட் உரிமைகள் மற்றும் wpa_supplicant.conf ஐப் படிக்க கோப்பு முறைமையில் சலசலக்கும் விருப்பம் தேவை என்று மட்டுமே நான் கூறுவேன். பயன்பாட்டு தர்க்கத்திற்கு வெளியில் இருந்து கடவுச்சொல்லை உள்ளிட வேண்டும் என்றால், வகுப்பின் மூலம் இணைப்பை ஏற்படுத்தலாம் android.net.wifi.WifiManager.

Спасибо எகோர் பொனோமரேவ் மதிப்புமிக்க சேர்த்தல்களுக்கு.

ஏதாவது சேர்க்க வேண்டும் அல்லது திருத்த வேண்டும் என்று நீங்கள் நினைத்தால், கருத்துகளில் எழுதுங்கள் :)

ஆதாரம்: www.habr.com

கருத்தைச் சேர்